2009-10-21 4 views
23

Chcę móc to zrobić:Skonstruuj XML z dynamiczną etykietą i atrybutami w Scali?

val myXml = <myTag { someAttributes }> </myTag> 

(bo nie wiem, co dane atrybutów są w czasie kompilacji)

a to:

val myXml = <{someTag}></{someTag}> 

Ten ISN 't poprawna składnia Scali. Najbliżej mogę użyć obiektu Elem do konstruowania elementów, ale to trochę kłopotliwe (wstawienie PCDATA tam, gdzie tego nie chcę). Czy jest jakikolwiek sposób robienia tego jak wyżej?

Odpowiedz

24
val myXml = <myTag/> % Attribute(None, "name", Text("value"), Null) 

Zobacz scala.xml.Attribute dla różnych konstruktorów.

Dodanie samego atrybutu dla wszystkich dzieci:

scala> val xml = <root><a/><b/><c/></root> 
xml: scala.xml.Elem = <root><a></a><b></b><c></c></root> 

scala> xml.child map (_ match { 
    | case elem : Elem => elem % Attribute(None, "name", Text("value"), Null) 
    | case x => x 
    | }) 
res3: Sequence[scala.xml.Node] = ArrayBuffer(<a name="value"></a>, <b name="value"></b>, <c name="value"></c>) 

Można również korzystać z rzeczy w scala.xml.transform to zrobić rekurencyjnie do wszystkich XML:

val rr = new RewriteRule { 
    override def transform(n: Node): Seq[Node] = n match { 
    case elem : Elem => elem % Attribute(None, "name", Text("value"), Null) toSeq 
    case other => other 
    } 
} 

val rt = new RuleTransformer(rr) 

scala> rt(xml) 
res5: scala.xml.Node = <root name="value"><a name="value"></a><b name="value"></b><c name="value"></c></root> 

Albo można dodać przypisuje dowolnych części xml:

scala> val xml = <root>{<a/> % Attribute(None, "name", Text("value"), Null)}</root> 
xml: scala.xml.Elem = <root><a name="value"></a></root> 

EDIT

Zmiana nazwy jest łatwe do zrobienia na Scala 2.8, tak:

val someTag = "tag" 
val myXml = <root>{<a/>.copy(label = someTag)}</root> 
+0

Dziękuję bardzo! – Joe

+1

To nie pozwala mi jednak utworzyć węzła z daną etykietą. Nie widzę sposobu na stworzenie dowolnej struktury XML. Ekstraktor dla Elem ma warargs dla dzieci. Chcę móc przekazać NodeSeq (dowolnej wielkości). – Joe

+0

jakikolwiek sposób utworzenia węzła, jak w drugim fragmencie w OP? – IttayD

8

Uwaga: trzeba

import scala.xml.Null 

aby uzyskać to do pracy, a nie scala.Null, które również istnieje.

+0

Dzięki! Po przeczytaniu odpowiedzi Daniela pomyślałem, że "Null" jest literówką i zamiast tego napisał "zerowy". – KajMagnus

Powiązane problemy