R xml-抓取子子子项并在子项中折叠,即使缺少元素文本

R xml-抓取子子子项并在子项中折叠,即使缺少元素文本,r,xml,xml2,R,Xml,Xml2,我有一个嵌套的xml数据集,如下所示,我正试图解析w/xml2和tidyverse包。有三个儿童信封。我想获取每个标记中和子子子标记的所有文本,并使用易于识别的分隔符(如;)折叠它们或从中列出data.frames MWE:以下是数据: 或者像下面这样的嵌套列表一样好(也许更好): [[1]] card_id value 1 605380 coke 2 610954 pizza 3 605381 surprise 4 610958 joke [[2]]

我有一个嵌套的xml数据集,如下所示,我正试图解析w/xml2tidyverse包。有三个儿童信封。我想获取每个
标记中
子子子标记的所有文本,并使用易于识别的分隔符(如
;)折叠它们或从中列出data.frames

MWE:以下是数据: 或者像下面这样的嵌套列表一样好(也许更好):

[[1]]
  card_id    value
1  605380     coke
2  610954    pizza
3  605381 surprise
4  610958     joke

[[2]]
  card_id         value
1  605381 charlie horse
2  605380       rug bug
3  610954    mario cart

[[3]]
  card_id   value
1  605377 trogdor
2    <NA>    jorb
3  605333    <NA>

不太漂亮,但您可以通过首先将每个信封的所有子元素放入单独的列表元素,然后循环获取每个卡id和值节点的文本来获取data.frames列表

myxml %>%
    xml_find_all('//envelope') %>%
    lapply(xml_children) %>%
    lapply(function(x) data.frame(
        card_id = xml_child(x, 'card-id') %>% xml_text,
        value = xml_child(x, 'value') %>% xml_text
        )
    )

#[[1]]
#  card_id    value
#1  605380     coke
#2  610954    pizza
#3  605381 surprise
#4  610958     joke
#
#[[2]]
#  card_id         value
#1  605381 charlie horse
#2  605380       rug bug
#3  610954    mario cart
#
#[[3]]
#  card_id   value
#1  605377 trogdor
#2            jorb
#3  605333  

对于NAs而不是“”,您可以在每个
xml\u文本之后添加
%%>%ifelse(.==”,NA,)
,然后在将其发送到Lappy之前将其转换为列表,这就是为什么它会对所有内容执行此操作。这就是管道操作符所做的(`%>%`)将事情推进到下一步,每次查看当前X时,Lappy都会在列表上迭代,该X是您提供给它的每个信封,因此它会对所有信封执行
xml\u find\u all\uuuuu
操作。如果您想要更多控制,请将信封作为列表保存到变量中,然后使用循环进行控制迭代,并使用逻辑语句解析子函数,或者构建一个复杂函数,对其进行广泛测试并将其仔细输入Lappy。如果您想与XML包进行比较,请尝试
Lappy(myxml[“//envelope]”,xmlToDataFrame)
Beauty。有助于我理解我对结构的理解。
[[1]]
  card_id    value
1  605380     coke
2  610954    pizza
3  605381 surprise
4  610958     joke

[[2]]
  card_id         value
1  605381 charlie horse
2  605380       rug bug
3  610954    mario cart

[[3]]
  card_id   value
1  605377 trogdor
2    <NA>    jorb
3  605333    <NA>
myxml %>%
    xml_find_all('//envelope') %>%
    as_list() %>%
    lapply(function(x){
        data_frame(
            card_id = x %>% xml_find_all('//card-id') %>% xml_text(),
            value = x %>% xml_find_all('//value') %>% xml_text()
        )
    })
myxml %>%
    xml_find_all('//envelope') %>%
    lapply(xml_children) %>%
    lapply(function(x) data.frame(
        card_id = xml_child(x, 'card-id') %>% xml_text,
        value = xml_child(x, 'value') %>% xml_text
        )
    )

#[[1]]
#  card_id    value
#1  605380     coke
#2  610954    pizza
#3  605381 surprise
#4  610958     joke
#
#[[2]]
#  card_id         value
#1  605381 charlie horse
#2  605380       rug bug
#3  610954    mario cart
#
#[[3]]
#  card_id   value
#1  605377 trogdor
#2            jorb
#3  605333