2

我想在运行时选择 xml 中的任意元素并更新其值。例如,给定 xml

<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))

RewriteRule 有可能吗?

4

1 回答 1

0

来自https://github.com/scala/scala-xml/issues/129

由于 Scala 的词法作用域规则,结果是不幸的名称冲突。这是这个类成员的结果:

http://www.scala-lang.org/api/current/scala-xml/scala/xml/transform/RewriteRule.html#name:String

https://github.com/scala/scala-xml/blob/4c09977/src/main/scala/scala/xml/transform/RewriteRule.scala#L23

更改变量名称可以解决问题。这是更新的代码。

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
      }
    })
  }

}
于 2017-01-25T14:39:12.570 回答