Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>So if I were in your position, I think what I'd really want to be writing is something like:</p> <pre><code>case elem: Elem =&gt; elem.copy(attributes= for (attr &lt;- elem.attributes) yield attr match { case attr@Attribute("attr1", _, _) =&gt; attr.copy(value=attr.value.text.toInt * 2) case attr@Attribute("attr2", _, _) =&gt; attr.copy(value=attr.value.text.toInt * -1) case other =&gt; other } ) </code></pre> <p>There are two reasons this won't work out of the box:</p> <ol> <li><code>Attribute</code> doesn't have a useful <code>copy</code> method, and </li> <li>Mapping over a <code>MetaData</code> yields an <code>Iterable[MetaData]</code> instead of a <code>MetaData</code> so even something as simple as <code>elem.copy(attributes=elem.attributes.map(x =&gt; x))</code> will fail.</li> </ol> <p>To fix the first problem, we'll use an implicit to add a better copy method to <code>Attribute</code>:</p> <pre><code>implicit def addGoodCopyToAttribute(attr: Attribute) = new { def goodcopy(key: String = attr.key, value: Any = attr.value): Attribute = Attribute(attr.pre, key, Text(value.toString), attr.next) } </code></pre> <p>It can't be named <code>copy</code> since a method with that name already exists, so we'll just call it <code>goodcopy</code>. (Also, if you're ever creating values that are <code>Seq[Node]</code> instead of things that should be converted to strings, you could be a little more careful with <code>value</code>, but for our current purposes it's not necessary.)</p> <p>To fix the second problem, we'll use an implicit to explain how to create a <code>MetaData</code> from an <code>Iterable[MetaData]</code>:</p> <pre><code>implicit def iterableToMetaData(items: Iterable[MetaData]): MetaData = { items match { case Nil =&gt; Null case head :: tail =&gt; head.copy(next=iterableToMetaData(tail)) } } </code></pre> <p>Then you can write code pretty much like what I proposed at the beginning:</p> <pre><code>scala&gt; val elem = &lt;b attr1 = "100" attr2 = "50"/&gt; elem: scala.xml.Elem = &lt;b attr1="100" attr2="50"&gt;&lt;/b&gt; scala&gt; elem.copy(attributes= | for (attr &lt;- elem.attributes) yield attr match { | case attr@Attribute("attr1", _, _) =&gt; | attr.goodcopy(value=attr.value.text.toInt * 2) | case attr@Attribute("attr2", _, _) =&gt; | attr.goodcopy(value=attr.value.text.toInt * -1) | case other =&gt; other | } | ) res1: scala.xml.Elem = &lt;b attr1="200" attr2="-50"&gt;&lt;/b&gt; </code></pre>
 

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