【发布时间】:2016-05-14 02:42:21
【问题描述】:
数据
我有一个类似这样结构的 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 的属性,并且除了顶级节点之外的所有节点都可以。
之前
我首先使用带有函数xmlTreeParse() 的XML 包解析此文档并存储根节点。然后我使用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() on。
即使我设法将所有节点的indexVector 和xmlSize() 映射到我可以直接在xmltop 上使用的正确索引,我仍然会遇到双括号数量可变的问题(xmltop[[1]][[3]]与xmltop[[1]][[2]][[1]])。
我还尝试了XML包的其他几个功能,包括xmlApply、getNodeLocation和getNodeSet,但它们似乎没有帮助。
我没有真正尝试过的东西
我不太了解xmlTreeParse()、xmlInternalTreeParse() 和xmlTreeParse(useInternalNodes = T) 的区别,而且我无法完全理解 XPath,所以我没有深入尝试使用它。
任何有用的指针将不胜感激。
【问题讨论】: