【问题标题】:Efficiently get the number of children with specific name using XML and R使用 XML 和 R 有效地获取具有特定名称的孩子的数量
【发布时间】:2013-04-03 14:55:37
【问题描述】:

我正在使用 R 和包 XML 解析巨大的 XML 文件。作为数据处理的一部分,我现在需要在一长串节点中,每个节点有多少特定名称的子节点(节点数可以超过 20.000)

我目前的做法是:

nChildrenWithName <- xpathSApply(doc, path="/path/to/node/*", namespaces=ns, xmlName) == 'NAME'
nChildren <- xpathSApply(doc, path="/path/to/node", namespaces=ns, fun=xmlSize)
nID <- sapply(split(nChildrenWithName, rep(seq(along=nChildren), nChildren)), sum)

这是我所能得到的矢量化。我仍然觉得这可以使用正确的 XPATH 表达式在一次调用中实现。不过,我对 XPATH 的了解有限,所以如果有人知道该怎么做,我将不胜感激……

最好的托马斯

【问题讨论】:

    标签: xml r xpath xml-parsing


    【解决方案1】:
    library(XML)
    doc <- xmlTreeParse(
      system.file("exampleData", "mtcars.xml", package="XML"),
      useInternalNodes=TRUE      )
    xpathApply(xmlRoot(doc),path="count(//variable)",xmlValue)
    

    【讨论】:

    • 不幸的是,这给了我节点总数 - 而不是每个父节点。我可能提出这个问题有点奇怪。 MiMo 的示例描述了我想要实现的目标......
    • 是的,请始终按照通常的要求添加示例数据。这样就清楚了。
    【解决方案2】:

    如果我理解正确的问题,有一个 XML 像:

    <path>
      <to>
        <node>
          <NAME>A</NAME>
          <NAME>B</NAME>
          <NAME>C</NAME>
        </node>
        <node>
          <NAME>X</NAME>
          <NAME>Y</NAME>
        </node>
      </to>
      <to>
        <node>
          <NAME>AA</NAME>
          <NAME>BB</NAME>
          <NAME>CC</NAME>
        </node>
      </to>
    </path>
    

    需要的是每个 node 下的 NAME 元素的数量 - 所以在上面的示例中是 3、2、3。

    这在 XPath 1.0 中是不可能的:表达式可以返回节点列表或单个值 - 但不能返回计算值列表。

    使用 XPath 2.0 你可以编写:

    for $node in /path/to/node return count($node/NAME)
    

    或者简单地说:

    /path/to/node/count(NAME)
    

    (你可以测试他们here)

    【讨论】:

    • 谢谢 - 你的问题是对的。很高兴知道当前的 xpath 实现无法做到这一点。我将查找支持 xpath 2 的 XML 包的更新
    • 不客气。我不知道 R,但在我看来 XML/XSLT/XPath 的东西是基于 Saxon 处理器的,它支持 2.0
    • 嗯...据我所见,它基于 AFAIK 仅支持 xpath 1.0 的 libxml2 C 解析器...但再次感谢...
    • 如果您找到解决方案 R/XPATH 2.0,请在此处发布。 Omegathat 中似乎没有。
    【解决方案3】:

    考虑MiMo提到的例子

    <path>
      <to>
        <node>
          <NAME>A</NAME>
          <NAME>B</NAME>
          <NAME>C</NAME>
        </node>
        <node>
          <NAME>X</NAME>
          <NAME>Y</NAME>
        </node>
      </to>
      <to>
        <node>
          <NAME>AA</NAME>
          <NAME>BB</NAME>
          <NAME>CC</NAME>
        </node>
      </to>
    </path>
    

    获取 /path/to/node 下的子节点数

    library(XML)
    doc = xmlParse("filename", useInternalNodes = TRUE)
    rootNode = xmlRoot(doc)
    childnodes = xpathSApply(rootNode[[1]][[1]], ".//NAME", xmlChildren)
    length(childnodes)
    [1] 3
    

    它会给你 3,类似地获取第二个节点下的子节点数,只需相应地传递索引,

    childnodes = xpathSApply(rootNode[[1]][[2]], ".//NAME", xmlChildren)
    length(childnodes)
    [1] 2
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-27
      • 1970-01-01
      • 1970-01-01
      • 2023-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-30
      相关资源
      最近更新 更多