Scala - 修改任意 XML 元素的值
Scala - Modify value of arbitrary XML element
我想在运行时选择 xml 中的任意元素并更新其值。例如,给定 xml like
<root>
<abc>123</abc>
<def>456</def>
</root>
我想在运行时(非硬编码)任意选择 <abc>
或 <def>
并更新其值。我在相关链接中发现了很多问题,但所有解决方案都预先设置了硬编码标签名称。
我尝试了将元素名称和新值作为参数的函数,例如
object RuleFactory {
// This function should not hard code literals "abc" or "def"
def createRuleTransformer(name:String, value : String) : RuleTransformer = {
new RuleTransformer(new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case elem @ Elem(prefix, label, attribs, scope, _) if elem.label.equalsIgnoreCase(name) => Elem(prefix, label, attribs, scope, false, Text(value))
case other => other
}
})
}
}
和
object RuleFactory {
def createRuleTransformer(name:String, value : String) : RuleTransformer = {
new RuleTransformer(new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case elem : Elem if elem.label.equalsIgnoreCase(name) => elem copy (child = Text(value) flatMap (this transform))
case other => other
}
})
}
}
然而,当我执行像
这样的转换时,两者都不会打印更新xml
val trasnformer = RuleFactory.createRuleTransformer("def", "2") // These params will be random
println(trasnformer(InputXml))
重写规则是否可行?
来自https://github.com/scala/scala-xml/issues/129
事实证明这是不幸的name-collision,因为 Scala 的词法范围规则。这是 class 成员的结果:
http://www.scala-lang.org/api/current/scala-xml/scala/xml/transform/RewriteRule.html#name:String
更改变量名解决问题。这是更新的代码。
object RuleFactory {
def createRuleTransformer(key:String, value : String) : RuleTransformer = {
new RuleTransformer(new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case elem @ Elem(prefix, label, attribs, scope, _) if elem.label.equalsIgnoreCase(key) =>
Elem(prefix, label, attribs, scope, false, Text(value))
case other => other
}
})
}
}
我想在运行时选择 xml 中的任意元素并更新其值。例如,给定 xml like
<root>
<abc>123</abc>
<def>456</def>
</root>
我想在运行时(非硬编码)任意选择 <abc>
或 <def>
并更新其值。我在相关链接中发现了很多问题,但所有解决方案都预先设置了硬编码标签名称。
我尝试了将元素名称和新值作为参数的函数,例如
object RuleFactory {
// This function should not hard code literals "abc" or "def"
def createRuleTransformer(name:String, value : String) : RuleTransformer = {
new RuleTransformer(new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case elem @ Elem(prefix, label, attribs, scope, _) if elem.label.equalsIgnoreCase(name) => Elem(prefix, label, attribs, scope, false, Text(value))
case other => other
}
})
}
}
和
object RuleFactory {
def createRuleTransformer(name:String, value : String) : RuleTransformer = {
new RuleTransformer(new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case elem : Elem if elem.label.equalsIgnoreCase(name) => elem copy (child = Text(value) flatMap (this transform))
case other => other
}
})
}
}
然而,当我执行像
这样的转换时,两者都不会打印更新xmlval trasnformer = RuleFactory.createRuleTransformer("def", "2") // These params will be random
println(trasnformer(InputXml))
重写规则是否可行?
来自https://github.com/scala/scala-xml/issues/129
事实证明这是不幸的name-collision,因为 Scala 的词法范围规则。这是 class 成员的结果:
http://www.scala-lang.org/api/current/scala-xml/scala/xml/transform/RewriteRule.html#name:String
更改变量名解决问题。这是更新的代码。
object RuleFactory {
def createRuleTransformer(key:String, value : String) : RuleTransformer = {
new RuleTransformer(new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case elem @ Elem(prefix, label, attribs, scope, _) if elem.label.equalsIgnoreCase(key) =>
Elem(prefix, label, attribs, scope, false, Text(value))
case other => other
}
})
}
}