鉴于此 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>
我需要对其进行转换,以便:
1)对于每个<item>
,<target>
的文本都根据<discriminator>
.
2)为每个<incomplete>
,添加一些文本内容。
根据其他 SO 帖子,到目前为止,我已经提出了 2) 的解决方案,使用RewriteRule
and RuleTransformer
. 它是这样的:
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)
这似乎工作正常,但我不知道:
- 如何实现 1)(根据兄弟元素修改元素)
- 如何结合这两个处理步骤。也就是说:在这种情况下,有两个不同的 RewriteRule-s 有意义吗?这两个是不是很浪费?在一次迭代中实现这两种转换是否可能/可取?
对于 1),我尝试对子列表进行模式匹配,如下所示:
case Elem("", "item", _, _, disc@Elem("", "discriminator", _, _, _*))
if discriminate(disc) => //...?
或这个:
case item@Elem("", "item", _, _, _*)
if discriminate(item \ "disc") => //..?
但这并没有那么好,因为我不知道如何只用替换来重新创建整个项目<target>
我什至不知道在这种情况下匹配反对<item>
是要走的路。但如果是的话,我能不能以某种方式实现它的<incomplete>
孩子的转变?
这里的正确方法是什么?