r - 从XML提取数据并传递到data.frame(使用NA表示丢失)

标签 r xml xpath xml-parsing

我有一个要从中提取数据的XML文件。到目前为止,我已经设法使用tidyverse和xml2软件包进行了所有操作,但是我仍无法弄清楚如何解决XML任务中的下一个难题。

样本XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:ArchiveView>
    <Notification ID="1001">
        <persons>
            <Timestamp>07:39:25</Timestamp>
            <person type="A" name="Barney">
                <uniqueUserId>2222</uniqueUserId>
            </person>
        </persons>
        <persons>
            <Timestamp>08:40:25</Timestamp>
            <person type="B" name="John">
                <uniqueUserId>1111</uniqueUserId>
            </person>
        </persons>
    </Notification>
    <Notification ID="1002">
        <persons>
            <Timestamp>14:39:25</Timestamp>
            <person type="A" name="Barney">
                <uniqueUserId>2222</uniqueUserId>
            </person>
        </persons>
    </Notification>
    <Notification ID="1003">
    </Notification>
</ns2:ArchiveView>


由于可以分配给一个通知的最大人数为3,因此我想得到一个看起来像这样的data.frame:

ID    name1    time1     type1    name2    time2     type2    name3    time3     type3
1001  Barney   07:39:25  A        John     08:40:25  B        NA       NA        NA
1002  Barney   14:39:25  A        NA       NA        NA       NA       NA        NA
1003  NA       NA        NA       NA       NA        NA       NA       NA        NA       


到目前为止,我设法做到了:

doc <- read_xml( "./data/test.xml" )


提取所有ID

df.ID <- data.frame( 
           ID = xml_find_all( doc, ".//Notifications" ) %>% xml_attrs() %>%  unlist() , 
           stringsAsFactors = FALSE )


标识已附加人员的通知的ID

ID.with.persons <- xml_find_all( doc, ".//Notifications[ persons ]" ) %>% 
                   xml_attrs() %>% 
                   unlist()


创建带有附加人员的通知节点集

nodes.persons <- xml_find_all( doc, ".//Notifications[ persons ]" 


我还设法获得了所有人的所有姓名(在一个向量中)

persons.name <- nodes.persons %>% xml_attr("name") %>% unlist()


我感觉自己已经很接近解决方案了,但是我无法确定如何将所有这些数据合并到一个不错的data.frame中(如上所述)。

所有建议都受到热烈的欢迎:)

最佳答案

这是一种非常熟练的方法(我对R很陌生,所以可能不太像R。)只需遍历每个元素,然后将所需的元素粘贴到向量中即可。最后将其转换为矩阵,然后将其插入数据框。这仅适用,因为有固定数量的列可用于构建矩阵。

library(xml2)
doc <- read_xml("test.xml")
row <- c()
notifications <- xml_find_all(doc, ".//Notification")
for (i in 1:length(notifications)) {
    row <- c(row, xml_attr(notifications[i], "ID"))
    for (j in 1:3) {
        person <- xml_find_all(notifications[i], sprintf("persons[%d]", j))
        if (length(person) > 0) {
            row <- c(row, xml_find_chr(person, "string(./person/@name)"))
            row <- c(row, xml_find_chr(person, "string(./Timestamp/text())"))
            row <- c(row, xml_find_chr(person, "string(./person/@type)"))
        } else {
            row <- c(row, NA, NA, NA)
        }
    }
}
df <- data.frame(matrix(data=rows, ncol=10, byrow=TRUE))
colnames(df) <- c("ID", "name1", "time1", "type1", "name2", "time2", "type2", "name3", "time3", "type3")
df




输出:

    ID  name1    time1 type1 name2    time2 type2 name3 time3 type3
1 1001 Barney 07:39:25     A  John 08:40:25     B  <NA>  <NA>  <NA>
2 1002 Barney 14:39:25     A  <NA>     <NA>  <NA>  <NA>  <NA>  <NA>
3 1003   <NA>     <NA>  <NA>  <NA>     <NA>  <NA>  <NA>  <NA>  <NA>

关于r - 从XML提取数据并传递到data.frame(使用NA表示丢失),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48925416/

相关文章:

python - 基于字典的关键词分类

r - shinydashboard 中的仪表板

R - 如果接下来的 x 行与前一行相比具有相等或更小的值,则识别行

ruby - 如何解析抓取的 JSON 字符串

r - 在日期向量 : Function very slow. 上使用 sapply 为什么?

python - 使用 lxml 和路径解析 xml,但如果它有 xmlns 声明,则得到空列表

c# - XML 文档 (1, 1) 中存在错误。反序列化一个简单的 xml 字符串时

java - 包含 ASSERT 标签的 XML 模式验证

javascript - 对 IE 上的 XPath 问题感到困惑

xpath 定位器在 FF3 中工作,但在 IE7 中不起作用