Construire du XML avec une étiquette dynamique et des attributs dans Scala?
Question
Je veux pouvoir faire ceci:
val myXml = <myTag { someAttributes }> </myTag>
(car je ne connais pas les détails de l'attribut au moment de la compilation)
et ceci:
val myXml = <{someTag}></{someTag}>
Ceci n’est pas une syntaxe Scala valide. Le plus proche que je puisse faire 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?
La solution
val myXml = <myTag/> % Attribute(None, "name", Text("value"), Null)
Voir scala.xml.Attribute
pour différents constructeurs.
Ajouter le 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 les éléments de scala.xml.transform pour le faire de manière récursive sur tous les fichiers 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>
Vous pouvez également ajouter des attributs à des parties arbitraires du code xml:
scala> val xml = <root>{<a/> % Attribute(None, "name", Text("value"), Null)}</root>
xml: scala.xml.Elem = <root><a name="value"></a></root>
MODIFIER
Changer le nom est facile à faire sur Scala 2.8, comme ceci:
val someTag = "tag"
val myXml = <root>{<a/>.copy(label = someTag)}</root>
Autres conseils
Remarque: vous devez
import scala.xml.Null
pour que cela fonctionne, et non pas scala.Null
, qui existe également.