我有几个XML文档,结构如下:
read_xml(filename, sep="")) %>% xml_find_all("//_atraso") %>% xml_structure
[[1]]
<_atraso>
<_omsmaximodia [_omsmaximodia]>
<_omsmaximo [_omsmaximo]>
<_omsmedia [_omsmedia]>
...
...
[[32]]
<_atraso>
<_omsmaximo [_omsmaximo]>
<_omsmedia [_omsmedia]>
...
可以看出,_atraso
父标记在某些项目上有_omsmaximodia
子标记,但在其他项目中没有(在这种情况下,在索引1处,子标记存在,而在索引32不是)。
我希望在它出现时读取_omsmaximodia
的值,否则为0或NA。目前我正在阅读它:
omsmaximodia <- read_xml(filename, sep="")) %>% xml_find_all("//_omsmaximodia") %>% xml_attr("_omsmaximodia") %>% gsub("\\.","",.) %>% gsub(",",".",.) %>% {as.numeric(.)}
但是,如果_omsmaximodia
标记不存在,则不会读取任何内容。运行上面的代码会产生长度为29的列表,因为32个项目中只有29个具有_omsmaximodia
标记。我需要长度为32,读取0或NA不存在。
我可以轻松地将NAs或0添加到列表中,但是读取项目的顺序很重要。也就是说,如果第30项没有_omsmaximodia
标签,那么列表中第30位的值必须是NA或0.只需将0或NA附加到列表的末尾是不可接受的。
我尝试使用xml_missing
和xml_has_attr
函数找出哪些索引不包含_omsmaximodia
标记,但这些函数似乎并不表示缺少标记,而我无法使用确定他们失踪的指数。
有什么想法吗?
答案 0 :(得分:2)
为了保留xml文档的结构,您可以尝试将函数分别应用于所有元素。以下示例说明了组成数据,因为您只绘制了数据结构。
# load packages and read data
library(xml2)
library(purrr)
input <- "<xml>
<_atraso>
<_omsmaximodia></_omsmaximodia>
</_atraso>
<_atraso>
</_atraso>
</xml>"
x <- read_xml(input)
x
#> {xml_document}
#> <xml>
#> [1] <_atraso>\n <_omsmaximodia/>\n</_atraso>
#> [2] <_atraso>\n </_atraso>
我们可以找到感兴趣的标签,但我们没有使用传统方法获得第二个标签的缺失值:
x %>%
xml_find_all(".//_omsmaximodia")
#> {xml_nodeset (1)}
#> [1] <_omsmaximodia/>
要解决此问题,我们会使用xml_children
更深入一级,然后映射所有元素。第二个元素的结果是空节点集。我们可以将map_if
与is_empty
结合使用,将其变为缺失值。
x %>%
xml_children() %>%
map(xml_find_all, ".//_omsmaximodia") %>%
map_if(is_empty, ~{.x <- NA})
#> [[1]]
#> {xml_nodeset (1)}
#> [1] <_omsmaximodia/>
#>
#> [[2]]
#> [1] NA
根据您的需要,您可以使用不同的功能来展平或修改列表结构。
请注意,使用此代码,第二个版本大约慢4倍。如果你这样做了几次,那没关系(第二个查询需要大约0.75ms,而第一个查询需要0.2ms),但如果你经常这样做(即解析许多文档),这可能会加起来。