R:将节点插入特定位置的xml树中

时间:2016-02-04 13:07:04

标签: xml r search insert tree

数据

我有一个像这样的结构的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]]包的其他几个功能,包括XMLxmlApplygetNodeLocation,但它们似乎没有帮助。

我还没有真正尝试过

我真的不明白getNodeSetxmlTreeParse()xmlInternalTreeParse()之间的区别,我无法围绕XPath,所以我没有尝试使用它。< / p>

非常感谢任何有用的指示。

1 个答案:

答案 0 :(得分:0)

我混淆的原因是?xmlElementsByTagName的帮助页面。它说:

  

&#34;添加递归参数使得此函数的行为类似于其他语言API中的 getElementsByTagName ,例如Java,C \#。但是,应该小心地理解,在那些语言中,人们会得到一组节点对象。这些节点引用了父母和孩子。因此,可以从每个节点导航树,找到它的关系等。在该包的当前版本中(并且对于可预见的未来),节点集是原始树中节点的“副本”。而且这些设施无法找到他们的兄弟姐妹或父母。&#34;

这让我觉得该函数返回一个副本列表而不是对节点本身的引用 如果使用设置为useInternalNodes的{​​{1}}函数的标志xmlTreeParse()解析xml,可能就是这种情况,但如果在解析时将其设置为FALSE,则TRUE返回的列表似乎包含实际参考 这些可以使用例如xmlElementsByTagName()轻松操作。

简而言之,我的问题的简单解决方案是:

addChildren()