Как назначить атрибут идентификатора с последовательным номером XML-файлу с помощью R?

#r #xml #text #tidyverse #data-wrangling

Вопрос:

У меня есть XML-файл, который выглядит так:

 <book id="1">
<sentence>word word word <lemma>word</lemma></sentence>
<sentence>word word word <lemma>word</lemma></sentence>
<sentence>word word word <lemma>word</lemma></sentence>
</book>
<book id="2">
<sentence>word word word <lemma>word</lemma></sentence>
<sentence>word word word <lemma>word</lemma></sentence>
<sentence>word word word <lemma>word</lemma></sentence>
</book>
<book id="3">
<sentence>word word word <lemma>word</lemma></sentence>
<sentence>word word word <lemma>word</lemma></sentence>
<sentence>word word word <lemma>word</lemma></sentence>
</book>
 

Я хочу использовать R для добавления атрибута id к каждому предложению и объекту леммы, чтобы они были последовательно пронумерованы, т. Е.,

 <book id="1">
<sentence id="1">word word word <lemma id="1">word</lemma></sentence>
<sentence id="2">word word word <lemma id="2">word</lemma></sentence>
<sentence id="3">word word word <lemma id="3">word</lemma></sentence>
</book>
<book id="2">
<sentence id="1">word word word <lemma id="1">word</lemma></sentence>
<sentence id="2">word word word <lemma id="2">word</lemma></sentence>
<sentence id="3">word word word <lemma id="3">word</lemma></sentence>
</book>
<book id="3">
<sentence id="1">word word word <lemma id="1">word</lemma></sentence>
<sentence id="2">word word word <lemma id="2">word</lemma></sentence>
<sentence id="3">word word word <lemma id="3">word</lemma></sentence>
</book>
 

Как мне это сделать?

Ответ №1:

Вот пример использования xml2 и purrr (для сопоставления по узлам). Во-первых, входные данные.

 library(xml2)
library(purrr)
xx <- read_xml('
<books>
  <book id="1">
    <sentence>word word word <lemma>word</lemma></sentence>
    <sentence>word word word <lemma>word</lemma></sentence>
    <sentence>word word word <lemma>word</lemma></sentence>
  </book>
  <book id="2">
    <sentence>word word word <lemma>word</lemma></sentence>
    <sentence>word word word <lemma>word</lemma></sentence>
    <sentence>word word word <lemma>word</lemma></sentence>
    </book>
    <book id="3">
      <sentence>word word word <lemma>word</lemma></sentence>
      <sentence>word word word <lemma>word</lemma></sentence>
      <sentence>word word word <lemma>word</lemma></sentence>
    </book>
</books>')
 

Тогда вы можете сделать

 xx %>% 
  xml_find_all("book") %>% 
  map(function(book) {
    book %>% 
      xml_find_all(".//lemma") %>% 
      imap(~xml_set_attr(.x, "id", .y))
  })
 

Вы просматриваете все книги, находите леммы и добавляете указатель.

Вы можете проверить результат, сохранив, а затем повторно прочитав данные в

 write_xml(xx, "new.xml")
cat(readLines("new.xml"), sep="n")
 

что дает

 <?xml version="1.0" encoding="UTF-8"?>
<books>
  <book id="1">
    <sentence>word word word <lemma id="1">word</lemma></sentence>
    <sentence>word word word <lemma id="2">word</lemma></sentence>
    <sentence>word word word <lemma id="3">word</lemma></sentence>
  </book>
  <book id="2">
    <sentence>word word word <lemma id="1">word</lemma></sentence>
    <sentence>word word word <lemma id="2">word</lemma></sentence>
    <sentence>word word word <lemma id="3">word</lemma></sentence>
  </book>
  <book id="3">
    <sentence>word word word <lemma id="1">word</lemma></sentence>
    <sentence>word word word <lemma id="2">word</lemma></sentence>
    <sentence>word word word <lemma id="3">word</lemma></sentence>
  </book>
</books>