Как преобразовать XML-файл в фрейм данных / тиббл в R?

Как преобразовать XML-файл, который выглядит так:

<bible>
  <b n="Psalm">
    <c n="1">
      <v n="1"> text text text text </v>
      <v n="2"> text text text text </v>
      <v n="3"> text text text text </v>
    </c>
    <c n="2">
      <v n="1"> text text text text </v>
      <v n="2"> text text text text </v>
      <v n="3"> text text text text </v>
  </c>
  </b>
  <b n="Revelation">
    <c n="1">
      <v n="1"> text text text text </v>
      <v n="2"> text text text text </v>
      <v n="3"> text text text text </v>
    </c>
    <c n="2">
      <v n="1"> text text text text </v>
      <v n="2"> text text text text </v>
      <v n="3"> text text text text </v>
    </c>
    <c n="3">
      <v n="1"> text text text text </v>
      <v n="2"> text text text text </v>
      <v n="3"> text text text text </v>
    </c>
  </b>
</bible>

В формат фрейма данных / таблицы, который выглядит следующим образом:

# A tibble: 15 x 4
 book       chapter verse text               
 <chr>        <dbl> <int> <chr>              
1 Psalm            1     1 text text text text
2 Psalm            1     2 text text text text
3 Psalm            1     3 text text text text
4 Psalm            2     1 text text text text
5 Psalm            2     2 text text text text
6 Psalm            2     3 text text text text
7 Revelation       1     1 text text text text
8 Revelation       1     2 text text text text
9 Revelation       1     3 text text text text
10 Revelation       2     1 text text text text
11 Revelation       2     2 text text text text
12 Revelation       2     3 text text text text
13 Revelation       3     1 text text text text
14 Revelation       3     2 text text text text
15 Revelation       3     3 text text text text

Я пробовал использовать xmlToDataFrame(nodes = getNodeSet(doc, "/bible")) из пакета XML, но получил только одно наблюдение с несколькими столбцами. Когда я попытался изменить уровни узлов для функции getNodeSet, я получил duplicate subscripts for columns ошибку. Спасибо.


person Mike Lee    schedule 04.10.2020    source источник


Ответы (1)


Рассмотрим XSLT, язык специального назначения, предназначенный для преобразования XML-файлов и их родственников в XPath. . В частности, вам необходимо сгладить все данные на одном уровне, таком как стих, где вы переносите узлы-предки или атрибуты на узлы-родственники, конечно же, повторяя значения для настройки фрейма данных.

После преобразования вы можете использовать удобный метод XML::xmlToDataFrame, подходящий для более плоского XML. R может запускать XSLT 1.0 с пакетом xslt (расширение до xml2)

XSLT (сохранить как .xsl, специальный файл .xml)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/bible">
        <xsl:copy>
            <xsl:apply-templates select="descendant::v"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="v">
        <data>
            <book><xsl:value-of select="ancestor::b/@n"/></book>
            <chapter><xsl:value-of select="ancestor::c/@n"/></chapter>
            <verse><xsl:value-of select="@n"/></verse>
            <text><xsl:value-of select="text()"/></text>
        </data>
    </xsl:template>

</xsl:stylesheet>

R (без циклов или сопоставления)

library(XML)
library(xslt)

doc <- read_xml("Import.xml", package = "xslt")
style <- read_xml("Script.xsl", package = "xslt")

new_xml <- xml_xslt(doc, style)

new_doc <- XML::xmlParse(new_xml)    
bible_df <- XML::xmlToDataFrame(nodes=getNodeSet(new_doc, "//data"))
person Parfait    schedule 04.10.2020