数据
我有一个类似下面这样的结构的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
的属性,除了顶层节点之外的所有节点都包含该属性。
Before
我首先使用XML
包中的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` 上使用的正确索引,我仍然会遇到一个变量数量的双括号问题(`xmltop[[1]][[3]]` vs `xmltop[[1]][[2]][[1]]`)。
我还尝试了
XML
包的其他几个函数,包括 xmlApply
、getNodeLocation
和 getNodeSet
,但它们似乎没有帮助。
我尚未真正尝试过的方法
我真的不理解xmlTreeParse()
、xmlInternalTreeParse()
和 xmlTreeParse(useInternalNodes=T)
的区别,也无法理解 XPath,因此我在尝试使用它时没有取得很大进展。任何有用的提示都将不胜感激。