扩展了我之前问过的有关如何迭代scala.xml.Node中的节点集合的问题here
我想进一步采取这一步,并询问我如何在递归函数中查看前一个孩子,以便在遇到特定情况后获取值
例如(标记在这里)
<html>
<head class="foo">
<title>Welcome</title>
</head>
<body>
<div>
<p>Foo</p>
</div>
</body>
</html>
使用我当前的实现(感谢@ knut-arne-vedaa)
def processNode(node: Node) {
if (node.isInstanceOf[Text]) {
if (node.text.contains("Welcome"))
{
//then inside here I want to go up to the prev element (head) and pull the class
}
}
node.child foreach processNode
}
我想添加另一个条件来从类部分
中获取文本“foo”知道我可以在if语句中直接添加这个值吗?另外如何从此fx返回String值?一个简单的回归线或?
答案 0 :(得分:4)
请注意,示例中Text节点的父节点实际上是&lt; title&gt;节点
由于节点没有对父母的引用,因此访问它们的一种方法就是在走树时随身携带它们,如下所示:
def processNode(node: Node, parent: Option[Node]) {
if (node.isInstanceOf[Text]) {
if (node.text.contains("Welcome"))
{
println("Node: " + node)
println("Parent: " + parent.getOrElse("[toplevel]"))
}
}
node.child foreach { n: Node => processNode(n, Some(node)) }
}
processNode(xml, None)
当然,当你想要将树重新爬回任意级别时,这会变得笨拙。一种方法是将节点包装在具有可选父引用的SuperNode
中。
case class SuperNode(current: Node, parent: Option[SuperNode] = None)
为方便起见,在没有父节点的默认情况下,创建一个隐式函数将节点转换为超节点。
implicit def nodeMakeSuper(n: Node) = SuperNode(n)
现在,您可以在树上向上导航任意次数,如下所示:
def processNode(node: SuperNode) {
node.current match {
case n @ Text(t) if t.contains("Welcome") => {
println("Node: " + n)
node.parent match {
case Some(p) => {
println("Parent: " + p.current)
p.parent match {
case Some(gp) => println("GrandParent: " + gp.current)
case None => println("No grandparent!")
}
}
case None => println("No parent!")
}
}
case _ => // these aren't the droids you're looking for
}
node.current.child foreach { child: Node => processNode(SuperNode(child, Some(node))) }
}
答案 1 :(得分:2)
如果你继续朝着这个方向前进,你应该使用XML Zipper。我认为Scalaz有一个(它有一个,但我不确定你是否可以将它用于XML)。
答案 2 :(得分:1)
如果你想使用值 来做某些事情,如果它在具有特定属性的节点内,你可以反过来做:首先找到具有给定属性的所有节点,然后对它们进行相关处理。
您可以找到“class”属性为“foo”的所有节点,如下所示:
xml \\ "_" filter { _.attribute("class") == Some(Text("foo")) }
编辑:您可以这样使用它:
val markup = <html>...etc
val filtered = markup \\ "_" filter { _.attribute("class") == Some(Text("foo")) }
filtered map processNode
如果你想从处理中返回某些值,你需要采用不同的方式,但你的问题并不明确。