我需要从XML中提取某些看起来像这样的数据(简化为简洁)
<Doc name="Doc1">
<Lists Count="1">
<List Name="List1">
<Points Count="3">
<Point Id="1">
<Tags Count ="1">"a"</Tags>
<Point Position="1" />
</Point>
<Point Id="2">
<Point Position="2" />
</Point>
<Point Id="3">
<Tags Count="1">"c"</Tags>
<Point Position="3" />
</Point>
</Points>
</List>
</Lists>
</Doc>
输出应该是一个数据框,它将标记和位置与每个点Id
相匹配 Point Tag Position
1 1 a 1
2 2 <NA> 2
3 3 c 3
我是XML新手,我正在玩xml2包。到目前为止,我可以单独提取每个变量,但由于某些点可能没有标记数据,我无法找到在三个参数之间进行匹配的方法。
> library(xml2)
> xml_data<-read_xml(...)
> xml_data %>% xml_find_all("//Point") %>% xml_attr("Id")
[1] "1" "2" "3"
> xml_data %>% xml_find_all("//Vertical") %>% xml_attr("Position")
[1] "1" "2" "3"
> xml_data %>% xml_find_all("//Tags") %>% xml_text()
[1] "\"a\"" "\"c\""
答案 0 :(得分:3)
purrr
和xml2
齐聚一堂:
library(xml2)
library(purrr)
txt <- '<Doc name="Doc1">
<Lists Count="1">
<List Name="List1">
<Points Count="3">
<Point Id="1">
<Tags Count ="1">"a"</Tags>
<Point Position="1" />
</Point>
<Point Id="2">
<Point Position="2" />
</Point>
<Point Id="3">
<Tags Count="1">"c"</Tags>
<Point Position="3" />
</Point>
</Points>
</List>
</Lists>
</Doc>'
doc <- read_xml(txt)
xml_find_all(doc, ".//Points/Point") %>%
map_df(function(x) {
list(
Point=xml_attr(x, "Id"),
Tag=xml_find_first(x, ".//Tags") %>% xml_text() %>% gsub('^"|"$', "", .),
Position=xml_find_first(x, ".//Point") %>% xml_attr("Position")
)
})
## # A tibble: 3 × 3
## Point Tag Position
## <chr> <chr> <chr>
## 1 1 a 1
## 2 2 <NA> 2
## 3 3 c 3
答案 1 :(得分:1)
在xpathApply
个节点上运行//Points/Point
,并为每个此类节点x
获取Id
,Tag
(如果没有,则为NA)和{ {1}}:
Position
,并提供:
library(XML)
doc <- xmlTreeParse(Lines, asText = TRUE, useInternalNodes = TRUE)
do.call("rbind", xpathApply(doc, "//Points/Point", function(x)
data.frame(Id = as.numeric(xmlAttrs(x)[["Id"]]),
Tags = c(gsub('"', '', xmlValue(x[["Tags"]])), NA)[[1]],
Position = as.numeric(xmlAttrs(x[["Point"]])[["Position"]],
stringsAsFactors = FALSE))))
<强>变化强>
以上给出相同答案的变体是这样的。在每个 Id Tags Position
1 1 a 1
2 2 <NA> 2
3 3 c 3
节点,它创建一个属性和值的字符串,然后使用Point
来读取它:
read.table
注意:输入library(XML)
doc <- xmlTreeParse(Lines, asText = TRUE, useInternalNodes = TRUE)
xp <- xpathSApply(doc, "//Points/Point", function(x) paste(
xmlAttrs(x)[["Id"]],
c(gsub('"', '', xmlValue(x[["Tags"]])), NA)[[1]],
xmlAttrs(x[["Point"]])[["Position"]]))
read.table(text = xp, col.names = c("Id", "Tags", "Position"), as.is = TRUE)
为:
Lines