Читать тексты XML в тиббл - PullRequest
1 голос
/ 25 мая 2019

Я хочу взять 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, но я не могу понять это.

1 Ответ

0 голосов
/ 25 мая 2019

Чтобы решить вашу проблему, необходимо проанализировать каждый div в отдельности, затем создать список фреймов данных и затем связать все вместе.

library(xml2)
library(tibble)

sample <- "2019-05-24.xml"

extract_data <- function(x){
  #read file
  file<-read_xml(x)
  #extract divs, get type attribute and 
  divs <- file %>% xml_find_all(".//div")
  type <- xml_attr(divs, "type")

  #find the head and p for each div
  #returns a list of data frames
  output<-lapply(divs, function(d){
    header<- d %>% xml_find_first(".//head") %>% xml_text()
    text<-d %>% xml_find_all(".//p") %>% xml_text() %>%  paste( collapse = ", ")
    data.frame(head=header, text)
  })
  #bind everything up into a tibble.
  answer<-do.call(rbind, output)
  test_tibble <- cbind(tibble(filename = x, seq = 1:nrow(answer), type = type), answer)
}

lapply(sample, extract_data)



#[[1]]
        filename seq    type               head                                       text
#1 2019-05-24.xml   1 article First test article Some information., Some other information.
#2 2019-05-24.xml   2 section         Test essay         An argument., Supporting evidence.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...