xml – Groovy Node.depthFirst()返回节点和字符串列表?
我希望有人能指出我在这里遗漏的明显事物.我觉得我已经这样做了一百次,并且由于某种原因,今晚,这种行为让我陷入了困境.
我正在从公共API读取一些XML.我想从某个节点(‘body’中的所有内容)中提取所有文本,其中还包括各种子节点.简单的例子: <xml> <metadata> <article> <body> <sec> <title>A Title</title> <p> This contains <italic>italics</italic> and <xref ref-type="bibr">xref's</xref> . </p> </sec> <sec> <title>Second Title</title> </sec> </body> </article> </metadata> </xml> 所以最终我想遍历所需节点内的树(再次,’body’)并提取其自然顺序中包含的所有文本.很简单,所以我只写了这个小的Groovy脚本…… def xmlParser = new XmlParser() def xml = xmlParser.parseText(rawXml) xml.metadata.article.body[0].depthFirst().each { node -> if(node.children().size() == 1) { println node.text() } } …继续炸毁“没有方法签名:java.lang.String.children()”.所以我在想自己“等等,什么?我会发疯吗?” Node.depthFirst()应该只返回一个Node的List.我添加了一个’instanceof’检查,果然,我得到了Node对象和String对象的组合.具体而言,不在同一行中的实体内的行将作为String返回,即“This contains”和“and”.其他一切都是节点(如预期的那样). 我可以轻松解决这个问题.然而,这似乎不是正确的行为,我希望有人可以指出我正确的方向. 解决方法
我很确定这是正确的行为(虽然我总是发现XmlSlurper和XmlParser有棘手的API).您可以迭代的所有东西都应该实现一个节点接口IMO,并且可能有一种TEXT类型,您可以使用它来从中获取文本.
那些文本节点是有效的节点,在许多情况下,你需要点击它,因为它首先通过XML进行深度遍历.如果它们没有返回,则用于检查子项大小为1的算法是否会起作用,因为某些节点(如< p>标记)在其下面同时包含混合文本和元素. 另外,为什么depthFirst不能始终返回文本是唯一子节点的所有文本节点,例如上面的斜体,会使事情变得更糟. 我倾向于使用groovy方法的签名来让运行时找出哪个是处理每个节点的正确方法(而不是使用像instanceof这样的东西),如下所示: def rawXml = """<xml> <metadata> <article> <body> <sec> <title>A Title</title> <p> This contains <italic>italics</italic> and <xref ref-type="bibr">xref's</xref> . </p> </sec> <sec> <title>Second Title</title> </sec> </body> </article> </metadata> </xml>""" def processNode(String nodeText) { return nodeText } def processNode(Object node) { if(node.children().size() == 1) { return node.text() } } def xmlParser = new XmlParser() def xml = xmlParser.parseText(rawXml) def xmlText = xml.metadata.article.body[0].'**'.findResults { node -> processNode(node) } println xmlText.join(" ") 打印 A Title This contains italics and xref's . Second Title 或者,XmlSlurper类可能会执行您想要/期望的更多内容,并且text()方法具有更合理的输出集.如果你真的不需要做任何类型的DOM与结果(XmlParser“更好”),我建议XmlSlurper: def xmlParser = new XmlSlurper() def xml = xmlParser.parseText(rawXml) def bodyText = xml.metadata.article.body[0].text() println bodyText 打印: A Title This contains italics and xref's . Second Title (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |