gpt4 book ai didi

xml - Scala:修改一个NodeSeq

转载 作者:数据小太阳 更新时间:2023-10-29 01:51:30 26 4
gpt4 key购买 nike

我有一个像这样的 NodeSeq:

<foo><br/>
<baz><bar key1="value1" key2="value2">foobar</bar></baz><br/>
Blah blah blah<br/>
<bar key1="value3">barfoo</bar><br/>
</foo>

我想为所有 bar 添加一个新属性的属性。我目前正在做:

   val rule = new RewriteRule() {
override def transform(node: Node): Seq[Node] = {
node match {
case Elem(prefix, "bar", attribs, scope, content@_*) => Elem(prefix, "bar", attribs append Attribute(None, "newKey", Text("newValue"), scala.xml.Null) , scope, content:_*)
case other => other
}
}
}

但问题是它只能在 1 个节点上工作。我希望它在所有节点上递归工作,如果我在 for 中调用转换循环,我无法用新值替换它们,因为它们变得不可变。我该如何解决这个问题?

最佳答案

这是您自己的解决方案的简化版本(使用 Daniel 的匹配逻辑变体):

def updateBar(node: Node): Node = node match {
case elem @ Elem(_, "bar", _, _, child @ _*) => elem.asInstanceOf[Elem] % Attribute(None, "newKey", Text("newValue"), Null) copy(child = child map updateBar)
case elem @ Elem(_, _, _, _, child @ _*) => elem.asInstanceOf[Elem].copy(child = child map updateBar)
case other => other
}

请注意,此代码与您的原始代码之间的主要区别在于,此代码从外部 处理节点,如此处所示,我在第一个答案中添加了一些打印语句:

scala> updateBar(<foo><bar>blabla</bar></foo>)
processing '<foo><bar>blabla</bar></foo>'
processing '<bar>blabla</bar>'
processing 'blabla'
result: 'blabla'
result: '<bar newKey="newValue">blabla</bar>'
result: '<foo><bar newKey="newValue">blabla</bar></foo>'
res1: scala.xml.Node = <foo><bar newKey="newValue">blabla</bar></foo>

虽然您的原始代码从由内而外 工作(简化示例):

scala> xf { <a><b><c/></b></a> }
transforming '<c></c>'
result: '<c></c>'
transforming '<b><c></c></b>'
result: '<b><c></c></b>'
transforming '<a><b><c></c></b></a>'
result: '<a><b><c></c></b></a>'
res4: scala.xml.Node = <a><b><c></c></b></a>

在某些情况下,这两种技术可能会产生不同的结果。

另一个区别是匹配代码稍微冗长:您需要一种情况用于相关元素的实际转换,另一种情况用于递归处理子节点。不过,所示示例可能需要稍微重构一下。

关于xml - Scala:修改一个NodeSeq,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4666717/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com