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

发布时间:2021-09-28 发布网站:前端之家 F2er.com
前端之家收集整理的这篇文章主要介绍了R:将节点插入特定位置的xml树中前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
数据

我有一个像这样的结构的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>

具体而言,任何标记节点的大小都是未知的,所有标记节点的属性数量不相等,并且属性的值不是唯一的.
然而,我所知道的是searchA属性的值是唯一的.此外,只有标记节点可以包含一个名为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()的节点.
即使我以某种方式设法将indexVector和所有节点的xmlSize()映射到我可以直接在xmltop上使用的正确索引,我仍然会遇到可变数量的双括号问题(xmltop [[1]] [ [3]] vs xmltop [[1]] [[2]] [[1]]).

我还尝试了XML包的其他几个函数,包括xmlApply,getNodeLocation和getNodeSet,但它们似乎没有帮助.

我没有真正尝试过的

我真的不明白xmlTreeParse(),xmlInternalTreeParse()和xmlTreeParse(useInternalNodes = T)的区别,我不能把我的脑袋包裹在XPath中,所以我没有尝试使用它.

任何有用的指针将非常感激.

解决方法

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

“The addition of the recursive argument makes this function behave like the getElementsByTagName in other language APIs such as Java,C\#. However,one should be careful to understand that in those languages,one would get back a set of node objects. These nodes have references to their parents and children. Therefore one can navigate the tree from each node,find its relations,etc. In the current version of this package (and for the forseeable future),the node set is a “copy” of the nodes in the original tree. And these have no facilities for finding their siblings or parent.”

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

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

addChildren(listOfNodes[indexVector],kids = list(newNode))

总结


以上是前端之家为你收集整理的R:将节点插入特定位置的xml树中全部内容,希望文章能够帮你解决R:将节点插入特定位置的xml树中所遇到的程序开发问题。

如果觉得前端之家网站内容还不错,欢迎将前端之家网站推荐给前端开发程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。