我有一个像这样的结构的xml文件(显示所需灵活性的大例子):
<rootnode sth="something" descr="ex">
<tag sth="sth1" descr="ex" anoAttr="sth2">
<tag sth="sth3" descr="ex2" searchA="sth4" anoAttr="sth5">
<tag sth="sth6" descr="ex3" oAttr="sth7" searchA="sth8" anoAttr="sth9">
<tag sth="sth10" descr="ex4" oAttr="sth11" searchA="sth12" anoAttr="sth13">
<someContent/>
</tag>
<someContent/>
</tag>
<tag sth="sth14" descr="ex5" oAttr="sth15" searchA="sth16" anoAttr="sth17">
<someContent/>
</tag>
<tag sth="sth1" descr="ex6" oAttr="sth15" searchA="sth18" anoAttr="sth17">
<someContent/>
</tag>
</tag>
<tag sth="sth10" descr="ex2" oAttr="sth19" searchA="sth20" anoAttr="sth9">
<someContent/>
</tag>
<tag sth="sth10" descr="ex7" searchA="sth21" anoAttr="sth13">
<tag sth="sth21" descr="ex8" oAttr="sth22" searchA="sth23" anoAttr="sth9">
<tag sth="sth23" descr="ex9" oAttr="sth22" searchA="sth24" anoAttr="sth5">
<someContent/>
</tag>
<someContent/>
</tag>
</tag>
</tag>
<otherNode>
<someNode/>
</otherNode>
</rootnode>
具体而言,任何tag
节点的大小都是未知的,所有tag
节点的属性数量不相等,属性值不唯一。
然而,我所知道的是searchA
属性的值是唯一的。此外,只有tag
个节点可以包含一个名为searchA
的属性,除了顶级节点之外的所有节点都可以。{/ p>
我首先使用带有函数XML
的{{1}}包解析此文档并存储根节点。然后,我使用xmlTreeParse()
创建一个新节点。
newXMLNode()
我的目标是将新创建的xmlfile = xmlTreeParse(filename, useInternalNodes = TRUE)
xmltop = xmlRoot(xmlfile)
newNode = newXMLNode(name = "newlyCreatedNode")
插入具有特定值的节点(例如newNode
)的子节点作为"sth23"
属性。
所以在这种情况下,我希望结果看起来像这样(注意底部附近的searchA
):
<newlyCreatedNode/>
基本上,在这种情况下,<rootnode sth="something" descr="ex">
<tag sth="sth1" descr="ex" anoAttr="sth2">
<tag sth="sth3" descr="ex2" searchA="sth4" anoAttr="sth5">
<tag sth="sth6" descr="ex3" oAttr="sth7" searchA="sth8" anoAttr="sth9">
<tag sth="sth10" descr="ex4" oAttr="sth11" searchA="sth12" anoAttr="sth13">
<someContent/>
</tag>
<someContent/>
</tag>
<tag sth="sth14" descr="ex5" oAttr="sth15" searchA="sth16" anoAttr="sth17">
<someContent/>
</tag>
<tag sth="sth1" descr="ex6" oAttr="sth15" searchA="sth18" anoAttr="sth17">
<someContent/>
</tag>
</tag>
<tag sth="sth10" descr="ex2" oAttr="sth19" searchA="sth20" anoAttr="sth9">
<someContent/>
</tag>
<tag sth="sth10" descr="ex7" searchA="sth21" anoAttr="sth13">
<tag sth="sth21" descr="ex8" oAttr="sth22" searchA="sth23" anoAttr="sth9">
<tag sth="sth23" descr="ex9" oAttr="sth22" searchA="sth24" anoAttr="sth5">
<someContent/>
</tag>
<someContent/>
<newlyCreatedNode/>
</tag>
</tag>
</tag>
<otherNode>
<someNode/>
</otherNode>
</rootnode>
可以获得我想要的结果。当然,我不想指定addChildren(xmltop[[1]][[3]][[1]], kids = list(newNode))
。
我可以使用[[1]][[3]][[1]]
获取所有相关节点的列表,并使用xmlElementsByTagName()
获取所有属性。我甚至可以得到一个逻辑索引向量,它给我正确的位置。
xmlAttrs()
我不知道如何使用此信息将我的节点插入正确位置的树中
listOfNodes = xmlElementsByTagName(el = xmltop, "tag", recursive = T)
attributeList = lapply(listOfNodes, FUN = function(x) xmlAttrs(x))
indexVector = sapply(attributeList, FUN = function(x) x["searchA"] == "sth23")
indexVector[is.na(indexVector)] = FALSE
listOfNodes[indexVector]
为我提供了正确的节点,但它现在是一个列表,而不是我可以使用listOfNodes[indexVector]
的节点。
即使我以某种方式设法将所有节点的addChildren()
和indexVector
映射到我可以直接在xmlSize()
上使用的正确索引,我仍然会遇到可变数量的问题双括号(xmltop
vs xmltop[[1]][[3]]
)。
我还尝试了xmltop[[1]][[2]][[1]]
包的其他几个功能,包括XML
,xmlApply
和getNodeLocation
,但它们似乎没有帮助。
我真的不明白getNodeSet
,xmlTreeParse()
和xmlInternalTreeParse()
之间的区别,我无法围绕XPath,所以我没有尝试使用它。< / p>
非常感谢任何有用的指示。
答案 0 :(得分:0)
我混淆的原因是?xmlElementsByTagName
的帮助页面。它说:
&#34;添加递归参数使得此函数的行为类似于其他语言API中的 getElementsByTagName ,例如Java,C \#。但是,应该小心地理解,在那些语言中,人们会得到一组节点对象。这些节点引用了父母和孩子。因此,可以从每个节点导航树,找到它的关系等。在该包的当前版本中(并且对于可预见的未来),节点集是原始树中节点的“副本”。而且这些设施无法找到他们的兄弟姐妹或父母。&#34;
这让我觉得该函数返回一个副本列表而不是对节点本身的引用
如果使用设置为useInternalNodes
的{{1}}函数的标志xmlTreeParse()
解析xml,可能就是这种情况,但如果在解析时将其设置为FALSE
,则TRUE
返回的列表似乎包含实际参考
这些可以使用例如xmlElementsByTagName()
轻松操作。
简而言之,我的问题的简单解决方案是:
addChildren()