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

标签 xml r search insert tree

数据

我有一个结构如下的 xml 文件(显示所需灵 active 的大示例):

<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 的属性除了顶级之外,所有其他人都这样做。

之前

我首先使用 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()上。
即使我以某种方式设法映射 indexVectorxmlSize()所有节点的正确索引,我可以在 xmltop 上使用直接地,我仍然会遇到双括号数量可变的问题( xmltop[[1]][[3]]xmltop[[1]][[2]][[1]] )。

我还尝试了 XML 的其他几个功能包,包括 xmlApply , getNodeLocationgetNodeSet , 但他们似乎没有帮助。

我还没有真正尝试过的

我不太明白 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."

这让我觉得该函数返回一个副本列表,而不是对节点本身的引用。
如果使用 xmlTreeParse() 函数的标志 useInternalNodes 设置为 FALSE 解析 xml,则可能会出现这种情况,但如果它是解析时设置为 TRUExmlElementsByTagName() 返回的列表似乎包含实际引用。
这些可以很容易地使用例如 addChildren() 进行操作。

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

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

关于xml - R:将节点插入特定位置的xml树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35201830/

相关文章:

r - 如何对 data.table 中的多个列进行分组?

java - 哪种数据结构更适合使用顺序搜索来搜索元素 - 数组列表还是链接列表?

python xml2dict 复杂的 xml

r - ggplot2 绘制两个图例

android - 段落行对齐 XML

r - 从 n 行的字符串中提取一个单词并将该单词附加为 R 中的新列

java - 在android中,如何搜索互联网并在 Activity 中返回结果?

node.js - 如何从每个索引中获取搜索结果

C#反序列化带有命名空间的xml

javascript - 如何用javascript读取这个xml文件?