我目前正在实现 xml 的 DFS 遍历,以便它到达每个叶节点并生成叶节点的路径。
给定 XML:
<vehicles>
<vehicle>
gg
</vehicle>
<variable>
</variable>
</vehicles>
输出(类似):
Map("gg" -> "vehicles/vehicle", "" -> "vehicles/variable")
如果有一个可用的库可以执行此操作,那就太好了,这样我就不必维护代码了。
谢谢。如有任何帮助,我们将不胜感激。
最佳答案
对于那些只想使用一个函数或更 XPath 友好的解决方案的人
我已经创建了一个存储库,它扩展了下面的代码,并且应该生成正确的 XPath,但是我将下面的代码保留为原样,因为它相对简单,并且是理解代码的一个很好的起点。 repo is on github .
回答
这是一个受 @Samar 答案启发的实现,它生成 XPath(到目前为止没有正确的属性表示法),是尾递归的,处理属性,并且不使用可变集合:
/**
* Helper function to add XPaths to a node sequence; assume a default of root nodes.
*/
def pathifyNodes(nodes: Seq[Node], parPath: String = "/"): Seq[(Node, String)] =
nodes.map{nn => (nn, parPath + nn.label + "/")}
@tailrec
final def uniqueXpaths(
nodes: Seq[(Node, String)], pathData: List[(String, String)] = Nil
): List[(String, String)] = nodes match {
case (node, currentPath) +: rest =>
val newElementData =
if(node.child.isEmpty) List((currentPath, node.text))
else Nil
val newAttributeData = node.attributes.asAttrMap.map{
case (key, value) => (currentPath + "@" + key, value)
}.toList
uniqueXpaths(
rest ++ node.child.flatMap(ns => pathifyNodes(ns, currentPath)),
newElementData ::: newAttributeData ::: pathData
)
case Seq() => pathData
}
像这样运行:
val x = <div class="content"><a></a><p><q>hello</q></p><r><p>world</p></r><s></s></div>
val xpaOut = uniqueXpaths(pathifyNodes(x))
欢迎提出建议。我计划修复属性处理以生成依赖于属性选择的正确 XPath,并且还可能尝试以某种合理的方式处理递归 XPath,但我怀疑这会大大增加代码大小,所以我想继续粘贴它.
关于xml - Scala:获取 XML 中的所有叶节点及其路径的最简单方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39001421/