r - 循环选择节点并选择第一个节点内任何级别的子节点
问题描述
我正在使用 xml2 包。我想要:
- 选择具有特定标签的节点(在本例中为 all
envelope
) - 循环遍历这些节点并选择其中的节点,而不考虑嵌套(在这种情况下,所有
value
标签都在card-entry
标签内) - 用空格连接文本
有三个信封,所以我希望能够从value
标签内找到的card-entry
标签内返回一个包含所有文本的三个向量。我无法做到这一点。我怎样才能做到这一点?为什么我下面的方法不起作用?
MWE
library(xml2)
myxml <- read_xml('
<inside>
<box>
<card-entry>
<card-id type="integer">605383</card-id>
<value>get well</value>
</card-entry>
</box>
<envelope>
<card-entry>
<card-id type="integer">605380</card-id>
<value>coke</value>
</card-entry>
<card-entry>
<card-id type="integer">610954</card-id>
<value>pizza</value>
</card-entry>
<card-entry>
<card-id type="integer">605381</card-id>
<value>surprise</value>
</card-entry>
<card-entry>
<card-id type="integer">610958</card-id>
<value>joke</value>
<random>true</random>
</card-entry>
</envelope>
<envelope>
<card-entry>
<card-id type="integer">605381</card-id>
<value>charlie horse</value>
</card-entry>
<card-entry>
<card-id type="integer">605380</card-id>
<value>rug bug</value>
</card-entry>
<subenvelope>
<value>dont get me</value>
</subenvelope>
<card-entry>
<card-id type="integer">610954</card-id>
<value>mario cart</value>
</card-entry>
</envelope>
<envelope>
<card-entry>
<card-id type="integer">605377</card-id>
<value>trogdor</value>
</card-entry>
<subenvelope>
<card-entry>
<card-id type="integer"></card-id>
<value>jorb</value>
</card-entry>
</subenvelope>
<card-entry>
<card-id type="integer">605333</card-id>
<value></value>
</card-entry>
</envelope>
</inside>
'
)
期望的输出
## [1] coke pizza surprise joke
## [2] charlie horse rug bug mario cart
## [3] trogdor jorb
我试过的
children <- lapply(xml2::xml_find_all(myxml, '//envelope'), xml2::xml_children)
rm_na <- function(x) x[!is.na(x)]
lapply(children, function(x){
paste(rm_na(unlist(xml2::xml_text(xml2::xml_child(x, '//card-entry//value')))), collapse = ' ')
})
## [[1]]
## [1] ""
##
## [[2]]
## [1] ""
##
## [[3]]
## [1] ""
##
## There were 11 warnings (use warnings() to see them)
lapply(children, function(x){
paste(rm_na(unlist(xml2::xml_text(xml2::xml_find_all(x, '//card-entry//value')))), collapse = ' ')
})
## [[1]]
## [1] "get well coke pizza surprise joke charlie horse rug bug mario cart trogdor jorb "
##
## [[2]]
## [1] "get well coke pizza surprise joke charlie horse rug bug mario cart trogdor jorb "
##
## [[3]]
## [1] "get well coke pizza surprise joke charlie horse rug bug mario cart trogdor jorb "
解决方案
在你的内部选择器上,你想让它相对于当前节点,所以你想要.//
而不是//
再次搜索整个树
sapply(xml_find_all(myxml,"//envelope"), function(x)
paste(xml_text(xml_find_all(x, ".//card-entry/value")), collapse=" ")
)
# [1] "coke pizza surprise joke"
# [2] "charlie horse rug bug mario cart"
# [3] "trogdor jorb "
推荐阅读
- mysql - 我可以使用 MySql FULLTEXT 搜索来查找使用部分字符串的匹配项吗?
- c - 两个 MSP430 之间的时序错误通信
- jquery - 列未正确对齐
- node.js - 无法使用 npm 创建 React js 应用程序
- javascript - ....js的标题
- angular - 如何在全球范围内更改 mat-datepicker 的输出?
- flutter - 使用 google_maps_flutter 时接受位置权限后我的位置按钮未显示?
- c# - Windows 10 上 C# 中的智能卡
- java - Java 常量继承
- python - PyQt4_如何从MainWindow返回LoginWindow?