iro*_*on9 5 xml tree search r insert
我有一个具有这样结构的 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>
Run Code Online (Sandbox Code Playgroud)
具体而言,任何tag节点的大小都是未知的,所有tag节点的属性数量并不相同,并且属性的值不是唯一的。
但是,我所知道的是该searchA属性的值是唯一的。此外,只有tag节点可以包含一个名为的属性,searchA并且除了顶级节点之外的所有节点都可以。
我首先使用XML带有函数的包解析这个文档xmlTreeParse()并存储根节点。然后我使用newXMLNode().
xmlfile = xmlTreeParse(filename, useInternalNodes = TRUE)
xmltop = xmlRoot(xmlfile)
newNode = newXMLNode(name = "newlyCreatedNode")
Run Code Online (Sandbox Code Playgroud)
我的目标是将我新创建的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>
Run Code Online (Sandbox Code Playgroud)
基本上,在这种情况下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]
Run Code Online (Sandbox Code Playgroud)
我不知道如何使用此信息将我的节点插入到树中正确位置。
listOfNodes[indexVector]给了我正确的节点,但它现在是一个列表,而不是我可以使用的节点addChildren()。
即使我以某种方式设法将所有节点的indexVector和映射xmlSize()到我可以xmltop直接使用的正确索引,我仍然会遇到双括号(xmltop[[1]][[3]]vs xmltop[[1]][[2]][[1]])数量可变的问题。
我还尝试了XML包的其他几个功能,包括xmlApply,getNodeLocation和getNodeSet,但它们似乎没有帮助。
我不太明白 , 的区别xmlTreeParse(),xmlInternalTreeParse()而且xmlTreeParse(useInternalNodes = T)我无法理解XPath,所以我在尝试使用它时并没有走得很远。
任何有用的指针将不胜感激。
我感到困惑的原因是 的帮助页面?xmlElementsByTagName。那里说:
\n\n\n“添加递归参数使得该函数的行为类似于其他语言 API(例如 Java、C# 等)中的getElementsByTagName。但是,人们应该小心地理解,在这些语言中,人们将返回一组节点对象。这些节点引用了它们的父节点和子节点。因此,可以从每个节点导航树,查找其关系等。在该包的当前版本中(以及在可预见的将来),节点集是 \xe2\x80原始树中节点的\x9ccopy\xe2\x80\x9d。并且这些节点没有找到其兄弟节点或父节点的工具。”
\n
这让我认为该函数返回副本列表而不是对节点本身的引用。\n如果在解析 xml 时将函数的标志设置为,
则可能会出现这种情况,但如果在解析时将其设置为,则返回的列表似乎包含实际引用。\n这些可以很容易地使用例如 进行操作。useInternalNodesxmlTreeParse()FALSETRUExmlElementsByTagName()addChildren()
简而言之,我的问题的非常简单的解决方案是:
\n\naddChildren(listOfNodes[indexVector], kids = list(newNode))\nRun Code Online (Sandbox Code Playgroud)\n