【问题标题】:xml2 - get information from parent nodes more efficientlyxml2 - 更有效地从父节点获取信息
【发布时间】:2018-04-07 10:41:13
【问题描述】:

我的 xml 看起来像这样:

...
<node id=1>
 <child>a</child>
 <child>b</child>
 <child>c</child>
</node>
<node id=2>
 <child>d</child>
 <child>e</child>
</node>
...

我正在寻找的是一个引用孩子各自父母的 data.frame:

node_id  child_text
      1           a
      1           b
      1           c
      2           d
      2           e

我只能想到 2 个使用 xml2 的解决方案:

(a) 使用 xml_find_all(...) 创建一组子节点,然后使用 for 循环遍历 xml 结构以获取所需信息。显然效率极低。

(b) 得到一组父节点和一组子节点。从父集合中提取信息并计算每个父母有多少个孩子。然后使用 rep(information, no_of_children) 从上面填充 node_id 列。更好,但仍然很愚蠢。

我认为必须有更有效的方法?我很高兴有任何建议,因为我现在使用这些方法一个多月了,同时处理千兆位的 - 效率极低的 - xml 格式的数据结构。我也不限于使用 xml2,如果这会大大提高性能,我还可以切换到另一种编程语言。唯一重要的部分是我想从那里直接将数据加载到数据库中。

【问题讨论】:

    标签: r xml xml2


    【解决方案1】:

    鉴于您给出的非常通用的示例,我将rvestpurrr 一起使用:

    x <- "<node id=1>
       <child>a</child>
       <child>b</child>
       <child>c</child>
      </node>
      <node id=2>
       <child>d</child>
       <child>e</child>
      </node>"
    
    
    library(rvest)
    library(purrr)
    
    read_html(x) %>% 
      html_nodes('node') %>% 
      map_df(~{
        .x %>% 
          html_nodes('child') %>% 
          html_text() -> child
        data.frame(child = child, stringsAsFactors = FALSE)
      }, .id = 'node')
    
    #>   node child
    #> 1    1     a
    #> 2    1     b
    #> 3    1     c
    #> 4    2     d
    #> 5    2     e
    

    还有一些基准可以与您的方法进行比较:

    rbenchmark::benchmark(read_html(xml) %>% 
                            html_nodes('node') %>% 
                            map_df(~{
                              .x %>% 
                                html_nodes('child') %>% 
                                html_text() -> child
                              data.frame(child = child, stringsAsFactors = FALSE)
                            }, .id = 'node'), columns = c('replications', 'elapsed', 'user.self'))
    #>   replications elapsed user.self
    #> 1          100   0.964     0.964
    

    【讨论】:

    • 实际上这种方法比我已经指出的方法慢很多:基准时间为您的方法:1.45 对于解决方案(a):0.46 对于解决方案(b):0.12
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-30
    • 2016-12-06
    • 1970-01-01
    相关资源
    最近更新 更多