Transforming an XML element based on its sibling, using scala.xml.transform.RuleTransformer -
given xml:
<root> <item> <discriminator>d1</discriminator> <target>t1</target> <subitem> <incomplete></incomplete> </subitem> <subitem> <incomplete></incomplete> </subitem> </item> <item> <discriminator>d2</discriminator> <target>t2</target> <subitem> <incomplete></incomplete> </subitem> </item> </root>
i need transform such that:
1) each <item>
, text of <target>
modified based on text in <discriminator>
.
2) each <incomplete>
, add text content.
based on other posts, far i've come solution 2), using rewriterule
, ruletransformer
. goes this:
object completeincomplete extends rewriterule { override def transform(n: node): seq[node] = n match { case elem(_, "incomplete", _, _, _*) => <incomplete>content</incomplete> case other => other } } object transform extends ruletransformer(completeincomplete) transform(xml)
this seems work fine, don't know:
- how achieve 1) (modifying element based on sibling)
- how combine 2 processing steps. is: make sense in case have 2 different rewriterule-s? 2 wasteful? possible/advisable achieve both transformations in single iteration?
for 1), have tried pattern match list of children, this:
case elem("", "item", _, _, disc@elem("", "discriminator", _, _, _*)) if discriminate(disc) => //...?
or this:
case item@elem("", "item", _, _, _*) if discriminate(item \ "disc") => //..?
but didn't work out well, because don't know how recreate whole item replacing <target>
i don't know if in case matching against <item>
way go. if is, can somehow achieve transformation of <incomplete>
children?
what correct approach here?
see if works you:
override def transform(n: node): seq[node] = n match { case el @ elem(_, "item", _, _, _*) => val children = el.child val disc = children.find(_.label == "discriminator") val content = children.collect{ case el @ elem(_, "target", _, _, _*) => <target>{el.text + disc.map(_.text).getorelse("")}</target> case e:elem => e } <item>{content}</item> case el @ elem(_, "incomplete", _, _, _*) => <incomplete>some content</incomplete> case other => other }
the xml structure immutable, when on particular element, can not access it's parent. because of that, chose approach problem #1 stopping on item
instead , replacing child content. hope looking for.
Comments
Post a Comment