2009-10-21 4 views
23

Je veux être en mesure de le faire:Construire XML avec étiquette dynamique et attributs dans Scala?

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

(parce que je ne sais pas ce que les détails d'attribut sont au moment de la compilation)

et ceci:

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

Ce ISN n'est pas une syntaxe Scala valide. Le plus proche que je peux venir est d'utiliser l'objet Elem pour construire des éléments, mais c'est un peu gênant (insérer PCDATA là où je ne le veux pas). Y a-t-il un moyen de le faire comme ci-dessus?

Répondre

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

Voir scala.xml.Attribute pour différents constructeurs.

Ajout du même attribut à tous les enfants:

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>) 

Vous pouvez également utiliser la substance dans scala.xml.transform de le faire récursive à tous 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> 

Ou vous pouvez ajouter les attributs des parties arbitraires du xml:

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

EDIT

Changer le nom est facile à faire sur Scala 2.8, comme ceci:

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

Merci beaucoup! – Joe

+1

Cela ne me permet pas de créer un nœud avec un label donné. Je ne peux pas voir un moyen de créer une structure XML arbitraire. L'extracteur pour Elem a un varargs pour les enfants. Je veux pouvoir passer un NodeSeq (de n'importe quelle taille). – Joe

+0

une façon de créer un nœud comme dans les deuxièmes extraits de l'OP? – IttayD

8

Note: vous devez

import scala.xml.Null 

pour obtenir ce travail, et non scala.Null, qui a également existe.

+0

Merci! Après avoir lu la réponse de Daniel, j'ai pensé que "Null" était une faute de frappe et j'ai écrit "null" à la place. – KajMagnus

Questions connexes