Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Ok, best effort, Scala 2.8. We need to reconstruct attributes, which means we have to decompose them correctly. Let's create a function for that:</p> <pre><code>import scala.xml._ case class GenAttr(pre: Option[String], key: String, value: Seq[Node], next: MetaData) { def toMetaData = Attribute(pre, key, value, next) } def decomposeMetaData(m: MetaData): Option[GenAttr] = m match { case Null =&gt; None case PrefixedAttribute(pre, key, value, next) =&gt; Some(GenAttr(Some(pre), key, value, next)) case UnprefixedAttribute(key, value, next) =&gt; Some(GenAttr(None, key, value, next)) } </code></pre> <p>Next, let's decompose the chained attributes into a sequence:</p> <pre><code>def unchainMetaData(m: MetaData): Iterable[GenAttr] = m flatMap (decomposeMetaData) </code></pre> <p>At this point, we can easily manipulate this list:</p> <pre><code>def doubleValues(l: Iterable[GenAttr]) = l map { case g @ GenAttr(_, _, Text(v), _) if v matches "\\d+" =&gt; g.copy(value = Text(v.toInt * 2 toString)) case other =&gt; other } </code></pre> <p>Now, chain it back again:</p> <pre><code>def chainMetaData(l: Iterable[GenAttr]): MetaData = l match { case Nil =&gt; Null case head :: tail =&gt; head.copy(next = chainMetaData(tail)).toMetaData } </code></pre> <p>Now, we only have to create a function to take care of these things:</p> <pre><code>def mapMetaData(m: MetaData)(f: GenAttr =&gt; GenAttr): MetaData = chainMetaData(unchainMetaData(m).map(f)) </code></pre> <p>So we can use it like this:</p> <pre><code>import scala.xml.transform._ val attribs = Set("attr1", "attr2") val rr = new RewriteRule { override def transform(n: Node): Seq[Node] = (n match { case e: Elem =&gt; e.copy(attributes = mapMetaData(e.attributes) { case g @ GenAttr(_, key, Text(v), _) if attribs contains key =&gt; g.copy(value = Text(v.toInt * 2 toString)) case other =&gt; other }) case other =&gt; other }).toSeq } val rt = new RuleTransformer(rr) </code></pre> <p>Which finally let you do the translation you wanted:</p> <pre><code>rt.transform(&lt;a&gt;&lt;b attr1="100" attr2="50"&gt;&lt;/b&gt;&lt;/a&gt;) </code></pre> <p>All of this could be simplified if:</p> <ul> <li>Attribute actually defined prefix, key and value, with an optional prefix</li> <li>Attribute was a sequence, not a chain</li> <li>Attribute had a map, mapKeys, mapValues</li> <li>Elem had a mapAttribute</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload