Как извлечь xml_attr и xml_text на разных уровнях с xml2 и purrr?
Я хочу извлечь информацию из файла XML и преобразовать ее в фрейм данных.
Информация хранится во вложенных узлах в виде текста XML, а также атрибутов XML:
Пример структуры:
<xmlnode node-id = "Text about xmlnode">
<xmlsubnode subnode-id = "123">
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
</xmlsubnode>
<xmlsubnode subnode-id = "456">
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
</xmlsubnode>
</xmlnode>
<xmlnode node-id = "Text about xmlnode">
<xmlsubnode subnode-id = "123">
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
</xmlsubnode>
<xmlsubnode subnode-id = "456">
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
<xmlsubsubnode>
I want to extract this text
</xmlsubsubnode>
</xmlsubnode>
</xmlnode>
Я хочу получить эту информацию:
* node-id (attribute)
* subnode-id (attribute)
* text in `xmlsubnodenode` (text)
Мне нужен длинный фрейм данных, как это:
node-id subnode-id text
Text about xmlnode 1 123 I want to extract this text
Text about xmlnode 1 123 I want to extract this text
Text about xmlnode 1 123 I want to extract this text
Text about xmlnode 1 123 I want to extract this text
Text about xmlnode 1 456 I want to extract this text
Text about xmlnode 1 456 I want to extract this text
Text about xmlnode 1 456 I want to extract this text
Text about xmlnode 1 456 I want to extract this text
Text about xmlnode 2 123 I want to extract this text
Text about xmlnode 2 123 I want to extract this text
Text about xmlnode 2 123 I want to extract this text
Text about xmlnode 2 123 I want to extract this text
Text about xmlnode 2 456 I want to extract this text
Text about xmlnode 2 456 I want to extract this text
Text about xmlnode 2 456 I want to extract this text
Text about xmlnode 2 456 I want to extract this text
Я пытался следовать подходу Дженни Брайан "Как приручить XML с помощью вложенных фреймов данных и мурлыкать", но он работает только на первом уровне.
xml <- xml2::read_xml("input/example.xml")
rows <-
xml %>%
xml_find_all("//xmlnode")
rows_df <- data_frame(row = seq_along(rows), nodeset = rows)
rows_df %>%
mutate(node_id = nodeset %>% map(~ xml_attr(., "node-id"))) %>%
select(row, node_id) %>%
unnest()
У вас есть идеи, чтобы получить эту информацию с purrr
?
1 ответ
Решение
Подход без необходимости разматывать / добавлять строки в другой фрейм данных: создать фрейм данных, содержащий строки для каждого subsubnode
и использовать purrr
вместе с xml2
выбрать и извлечь значения xmlsubnode
родитель и xmlnode
предок.
Рабочий образец:
library(dplyr)
library(xml2)
library(purrr)
library(tidyr)
xml <- xml2::read_xml("input/example.xml")
rows <- xml %>% xml_find_all("//xmlsubsubnode")
rows_df <- data_frame(node = rows) %>%
mutate(node_id = node %>% map(~ xml_find_first(., "ancestor::xmlnode")) %>% map(~ xml_attr(., "node-id"))) %>%
mutate(subnode_id = node %>% map(~ xml_parent(.)) %>% map(~ xml_attr(., "subnode-id"))) %>%
mutate(text = node %>% map(~ xml_text(.))) %>%
select(-node)