在scala中给定XPath更改XML的最简单方法是什么?

时间:2016-09-01 16:21:04

标签: xml scala xpath scala-xml

val template = <root>
    <component>
        <mother-board>
            <manufacturer>
                <name>
                </name
            </manufacturer>
            <price>
                555
            </price>
            <chipset>
                Intel
            </chipset>
        </mother-board>
    </component>
</root>

val xPaths = Map("root/component/mother-board/manufacturer/name" -> "Asus")

val output = <root>
    <component>
        <mother-board>
            <manufacturer>
                <name>
                  Asus
                </name>
            </manufacturer>
            <price>
                555
            </price>
            <chipset>
                Intel
            </chipset>
        </mother-board>
    </component>
</root>

真正的模板超过250行,需要填充的xpath数量超过70.任何有关库或任何其他可以实现此目的的方法的建议都是受欢迎的。谢谢。

更新以添加有关我的方法的信息
到目前为止我所做的不起作用: 我基于可用的XPath创建XML。但是,如果处理XPath的顺序发生变化,那么XML也会发生变化,这是我的用例所不能接受的。

object Main extends App {
  val props = Map(
    "a/b/c" -> "val1",
    "a/b/d/f" -> "val3",
    "a/b/d/e" -> "val2"
  )

  println(props.keys.foldLeft(<root/>: Node)((acc, current) => {
    create(Elem(acc.prefix, acc.label, acc.attributes, acc.scope, true, acc.child: _*), current.split("/").toList, current, props)
  }))

  def create(node: Elem, path: List[String], completePath: String, propMap: Map[String, String]): Node = {
    if(path.size > 0) {
      val current = path.head
      node.child.filter(x => x.label.equals(current)).headOption.map(childToTraverse => {
        val newChild = create(Elem(null, childToTraverse.label, childToTraverse.attributes, childToTraverse.scope, false, childToTraverse.child: _*), path.tail, completePath, propMap)
        node.copy(child = node.child.filter(x => !x.label.equals(current)) ++ newChild)
      }).getOrElse({
        val newNode = Elem(null, current, node.attributes, node.scope, false)
        val newChild = create(newNode, path.tail, completePath, propMap)
        node.copy(child = node.child ++ newChild)
      })
    }
    else {
      node.copy(child = new Text(propMap.get(completePath).getOrElse("Value Not Available")))
    }
  }
}

问题:

输入:

"a/b/c" -> "val1",
"a/b/d/f" -> "val3",
"a/b/d/e" -> "val2"

它生成:

<root>
    <a>
        <b>
            <c>
                val1
            </c>
            <d>
                <f>
                    val3
                </f>
                <e>
                    val2
                </e>
            </d>
        </b>
    </a>
</root>

输入:

"a/b/c" -> "val1",
"a/b/d/e" -> "val2",
"a/b/d/f" -> "val3"

它生成:

<root>
    <a>
        <b>
            <c>
                val1
            </c>
            <d>
                <e>
                    val2
                </e>
                <f>
                    val3
                </f>
            </d>
        </b>
    </a>
</root>

请注意以不同顺序处理的相同XPath生成的两个XML的差异 我知道正确的顺序。所以我想拥有模板并根据XPath更改模板,而不是从头开始生成XML。

0 个答案:

没有答案