Große Antworten oben! Wenn Sie zu einem späteren Zeitpunkt mit einem komplexen XML-Code konfrontiert werden, der einen R-Import erfordert, sollten Sie das XML-Dokument mit XSLT (eine deklarative deklarative Programmiersprache, die XML-Inhalte in verschiedene Endbenutzer-Anforderungen umwandelt) neu strukturieren. Dann verwenden Sie einfach Rs xmlToDataFrame()
Funktion aus dem XML-Paket.
Leider verfügt R über kein dediziertes XSLT-Paket, das auf allen Betriebssystemen auf CRAN-R verfügbar ist. Das gelistete SXLT scheint ein Linux-Paket zu sein und kann nicht unter Windows verwendet werden. Siehe unbeantwortete SO-Fragen here und here. Ich verstehe @hrbrmstr (oben) unterhält eine GitHub XSLT project. Nichtsdestoweniger unterhalten fast alle Universalsprachen XSLT-Prozessoren, einschließlich Java, C#, Python, PHP, Perl und VB.
Unten ist die Open-Source-Python-Route und weil das XML-Dokument ziemlich nuanciert ist, werden zwei XSLTs verwendet (natürlich können XSLT-Gurus sie zu einem kombinieren, aber ich versuchte es nicht.
FIRST XSLT (unter Verwendung eines recursive template)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Identity Transform -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="record/text()" name="tokenize">
<xsl:param name="text" select="."/>
<xsl:param name="separator" select="' '"/>
<xsl:choose>
<xsl:when test="not(contains($text, $separator))">
<data>
<xsl:value-of select="normalize-space($text)"/>
</data>
</xsl:when>
<xsl:otherwise>
<data>
<xsl:value-of select="normalize-space(substring-before($text, $separator))"/>
</data>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $separator)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="description|variables|categoricalvariable|realvariable">
</xsl:template>
SECOND XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Identity Transform -->
<xsl:template match="records">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="record">
<record>
<area_name><xsl:value-of select="@label"/></area_name>
<area><xsl:value-of select="data[1]"/></area>
<region><xsl:value-of select="data[2]"/></region>
<palmitic><xsl:value-of select="data[3]"/></palmitic>
<palmitoleic><xsl:value-of select="data[4]"/></palmitoleic>
<stearic><xsl:value-of select="data[5]"/></stearic>
<oleic><xsl:value-of select="data[6]"/></oleic>
<linoleic><xsl:value-of select="data[7]"/></linoleic>
<linolenic><xsl:value-of select="data[8]"/></linolenic>
<arachidic><xsl:value-of select="data[9]"/></arachidic>
<eicosenoic><xsl:value-of select="data[10]"/></eicosenoic>
</record>
</xsl:template>
</xsl:stylesheet>
Python (mit lxml Modul)
import lxml.etree as ET
cd = os.path.dirname(os.path.abspath(__file__))
# FIRST TRANSFORMATION
dom = ET.parse('http://www.ggobi.org/book/data/olive.xml')
xslt = ET.parse(os.path.join(cd, 'Olive.xsl'))
transform = ET.XSLT(xslt)
newdom = transform(dom)
tree_out = ET.tostring(newdom, encoding='UTF-8', pretty_print=True, xml_declaration=True)
xmlfile = open(os.path.join(cd, 'Olive_py.xml'),'wb')
xmlfile.write(tree_out)
xmlfile.close()
# SECOND TRANSFORMATION
dom = ET.parse(os.path.join(cd, 'Olive_py.xml'))
xslt = ET.parse(os.path.join(cd, 'Olive2.xsl'))
transform = ET.XSLT(xslt)
newdom = transform(dom)
tree_out = ET.tostring(newdom, encoding='UTF-8', pretty_print=True, xml_declaration=True)
xmlfile = open(os.path.join(cd, 'Olive_py.xml'),'wb')
xmlfile.write(tree_out)
xmlfile.close()
R
library(XML)
# LOADING TRANSFORMED XML INTO R DATA FRAME
doc<-xmlParse("Olive_py.xml")
xmldf <- xmlToDataFrame(nodes = getNodeSet(doc, "//record"))
View(xmldf)
Ausgabe
area_name area region palmitic palmitoleic stearic oleic linoleic linolenic arachidic eicosenoic
North-Apulia 1 1 1075 75 226 7823 672 na 60
North-Apulia 1 1 1088 73 224 7709 781 31 61 29
North-Apulia 1 1 911 54 246 8113 549 31 63 29
North-Apulia 1 1 966 57 240 7952 619 50 78 35
North-Apulia 1 1 1051 67 259 7771 672 50 80 46
...
(leichte Bereinigung auf erster Platte wird als ein zusätzlicher Raum benötigt wurde hinzugefügt, nachdem "na" in xml doc, so wurden arachidic
und eicosenoic
nach vorne verschoben)
Ich würde xml2 verwenden, wenn auch nur weil Hadley durchweg sehr hochwertige und nützliche R-Pakete produziert. Es wird wahrscheinlich reibungsloser laufen und besser dokumentiert werden. Unterschiede unten in Readme: https://github.com/hadley/xml2 –
Fair genug. Xml2, nach der GitHub-Seite, und meine kurzen Erfahrungen, hat eine einfachere Schnittstelle. R wurde von R-Core-Entwicklern geschrieben und ist von Macken durchsetzt, während Hadley oft die Einfachheit gegenüber der Leistungsbilanz richtig macht und alles sauber und ordentlich macht. –