我有一个看起来像这样的xml文件(使用R来解析代码):
code <- '<a>
<b>
<c>1</c>
<c>2</c>
</b>
<b>
<c>3</c>
<c>4</c>
</b>
<c>5</c>
<c>6</c>
<b>
<c>7</c>
<c>8</c>
</b>
<c>9</c>
<c>10</c>
</a>'
library(XML)
parsed <- xmlParse(code)
我正在处理的问题是该文件因我需要的目的而部分格式错误。正确的格式要求每个c节点必须嵌套在b标签中。正如您所看到的那样,某些节点是正确的,但对于值为5,6,9,10的c节点则不然。
我知道如何使用XML包处理和编辑XML节点。我现在面临的问题是我需要单独解决两组c节点,即我需要提出一个XPath表达式,将c节点(5,6)识别为一组c节点(9,10) )作为另一组。一个简单的&#34; // c&#34;只识别不是我想要的所有c节点。
我以为我分享了我提出的解决方案。它从chorobas XPath开始,然后将兄弟链连接到此节点,检查它们的名称并重复此过程,直到它到达b节点。也许这有助于某人。
node1 <- XML::getNodeSet(parsed, "/a/c[preceding-sibling::*[1]/self::b]")
if(length(node1) > 0){
for(i in 1:length(node1)){
node.container <- list()
node.container[[1]] <- node1[[i]]
gg <- 1
repeat{
sibling.node <- XML::getSibling(node.container[[gg]])
if(is.null(sibling.node)) break
if(!(XML::xmlName(sibling.node) == "c"))) break
node.container[[gg + 1]] <- sibling.node
gg <- gg + 1
}
invisible(new.b <- XML::newXMLNode("b"))
invisible(XML::replaceNodes(oldNode = node1[[i]], newNode = new.b))
invisible(XML::addChildren(new.b, node.container))
}
}
答案 0 :(得分:1)
XPath无法返回节点组,它会返回一个节点列表。你可以轻松地让它返回对中的第一个:
/a/c[preceding-sibling::*[1]/self::b]
(即c
下的a
,其前一个兄弟是b
),
或者,如果结构在某个更深的地方
//c[parent::a][preceding-sibling::*[1]/self::b]
要进入第二个节点,只需使用following-sibling::c[1]
。
注意:强>
在c
的最开始,这不会抓住a
对。
答案 1 :(得分:0)
您可以使用
找到c
不是b
子节点的所有getNodeSet(parsed, "//c[name(parent::*)!='b']")
个节点
c
如果你想要那些后跟badc <- getNodeSet(parsed, "//c[name(parent::*)!='b' and name(following-sibling::*)='c']")
(一对的开头)的人。你可以做到。
xmlApply(badc, xpathSApply, "./following-sibling::c[1]")
你可以通过
获得下一对Object.observe