do you know any Scala API to insert and (or) update Nodes according to XPath? e.g for a given Node and XPath, this API would create a copy of XML with new node
thanks
You can use the RewriteRule
to do this, 2.10.3 documentation.
val cats = <Cats>
<Cat Name="Floyd"/>
<Cat Name="Onyx"/>
</Cats>
Then suppose the RewriteRule
class AddCat(name: String) extends RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case e: Elem if e.label == "Cats" =>
val cats = (e \\ "Cat")
val newCat = <Cat Name={name}/>
new Elem(e.prefix, "Cats", e.attributes, e.scope, e.minimizeEmpty, (cats ++ newCat).toSeq:_*)
case x => x
}
}
Then you could do,
val rule = new RuleTransformer(new AddCat("Stevie"))
rule.transform(cats)
res2: Seq[scala.xml.Node] = List(<Cats><Cat Name="Floyd"/><Cat Name="Onyx"/><Cat Name="Stevie"/></Cats>)
Similarly if you wanted to change an attribute
class AddLastName(name: String, lastName: String) extends RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case e: Elem if e.label == "Cat" && (e \\ "@Name" text).equals(name) =>
val cat: String = e.attributes("Name").head.text
e % Attribute(None, "Name", Text(s"$name $lastName"), Null)
case x => x
}
}
val rule = new RuleTransformer(new AddLastName("Stevie", "Nicks"))
rule.transform(cats)
res3: Seq[scala.xml.Node] = List(<Cats><Cat Name="Floyd"/><Cat Name="Onyx"/><Cat Name="Stevie Nicks"/></Cats>)
Both of these approaches would do what you're looking for. The hard part is figuring out how to get at the children, then build the parent node.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With