Я хочу взять XML-файл (который я называю "2019-05-24.xml") примерно так:
<file>
<header>
<filename>2019-05-24</filename>
</header>
<body>
<div type="article">
<head>First test article</head>
<p>Some information.</p>
<p>Some other information.</p>
</div>
<div type="section" feature="essay">
<head>Test essay</head>
<p>An argument.</p>
<p>Supporting evidence.</p>
</div>
</body>
</file>
и превратить его в тибл, как это
# A tibble: 3 x 6
filename seq type feature head text
<chr> <int> <chr> <chr> <chr> <chr>
1 2019-05-24.xml 1 article NA First test "Some information. Other information. Yet…
2 2019-05-24.xml 2 section essay Test essay "An argument. Supporting evidence."
3 2019-05-24.xml 3 index NA NA "Article.....1 Essay....2"
Это заставляет меня на полпути:
sample <- "2019-05-24.xml"
extract_data <- function(x){
divs <- x %>%
read_xml() %>%
xml_child(2) %>%
xml_find_all(".//div")
text <- xml_text(divs)
type <- xml_attr(divs, "type")
feature <- xml_attr(divs, "feature")
seq <- seq_along(divs)
test_tibble <- tibble(filename = x, seq = seq, type = type, feature = feature, text = text)
}
lapply(sample, extract_data)
К сожалению, результат объединяет текст head
и p
:
# A tibble: 3 x 5
filename seq type feature text
<chr> <int> <chr> <chr> <chr>
1 2019-05-24.… 1 article NA "First test articleSome information.\n Other in…
2 2019-05-24.… 2 section essay Test essayAn argument.Supporting evidence.
3 2019-05-24.… 3 index NA Article.....1Essay....2
Задача 1: голова
Если я извлеку head
таким же образом, я извлек текст
head <- sample %>%
read_xml() %>%
xml_child(2) %>%
xml_find_all(".//div/head//text()")
Я получаю сообщение об ошибке, поскольку третий div
не содержит head
:
Error: Tibble columns must have consistent lengths, only values of length one are recycled:
* Length 2: Column `head`
* Length 3: Columns `seq`, `type`, `feature`
Можно ли заставить эту функцию возвращать NA
, если в div
нет head
?
Проблема 2: чтение текста внутри div
Я хочу читать только текст в каждом из трех элементов или узлов в списке divs
. Можно ли заставить что-то вроде text <- divs %>% xml_children %>% xml_text()
(которое возвращает каждого дочернего элемента во всем файле) работать на каждом узле индивидуально? Я пробовал различные варианты apply()
. Я думаю, что я делаю что-то не так с XPath и xml_find_all
и xml_text
, но я не могу понять это.