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

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -