【问题标题】:Complex XML Parsing in RR 中的复杂 XML 解析
【发布时间】:2018-08-24 18:14:15
【问题描述】:

我正在尝试解析嵌套的 xml 文件。

<GENERIC_ROUGHDRAFT>
     <HEADER compName="California" dateCreated="2018-08-07">
      <COMP_INFO>
    </HEADER>
     <COVERSHEET>
      <ESTIMATE_INFO eName="MATTHEW_ANDERSON" iName="Matthew Anderson" priceList="MAY18" laborEff="Restoration/Service/Remodel" claimNumber="01" policyNumber="00000000000" typeOfLoss="Hail" deprNonMat="1" deprOandP="1" deprTaxes="1" onsite="1" recipientsXNAddress="California_BD" carrierId="111111" estimateType="Structural"/>
      <ADDRESSES>
       <ADDRESS type="Property" street="123 Street Cr" city="Idaho Falls" state="ID" zip="00000" primary="1"/>
       <ADDRESS type="Home" street="123 Street Cr" city="City" state="ID" zip="00000"/>
      </ADDRESSES>
  </COVERSHEET>
</GENERIC_ROUGHDRAFT>

我正在尝试提取 iName 和价目表等信息。

对于我的最终产品,我希望有一个数据框,其中信息看起来像一行,仅包含以下内容:

compName  |  dataCreated  | iName  |  Type  | Street|  | State

没有太多关于如何在一个段内提取多个数据的文档。

有什么建议吗?

【问题讨论】:

    标签: r xml parsing


    【解决方案1】:

    XML 文件可能有很多嵌套,这使得它们难以直接转换为 data.frame。我认为提取这些文件的最简单方法是使用xslt 将它们重塑为更表格的形式。

    使用您的样本数据

    library(xml2)
    xml <- read_xml('<GENERIC_ROUGHDRAFT>
         <HEADER compName="California" dateCreated="2018-08-07">
          <COMP_INFO/>
        </HEADER>
         <COVERSHEET>
          <ESTIMATE_INFO eName="MATTHEW_ANDERSON" iName="Matthew Anderson" priceList="MAY18" laborEff="Restoration/Service/Remodel" claimNumber="01" policyNumber="00000000000" typeOfLoss="Hail" deprNonMat="1" deprOandP="1" deprTaxes="1" onsite="1" recipientsXNAddress="California_BD" carrierId="111111" estimateType="Structural"/>
          <ADDRESSES>
           <ADDRESS type="Property" street="123 Street Cr" city="Idaho Falls" state="ID" zip="00000" primary="1"/>
           <ADDRESS type="Home" street="123 Street Cr" city="City" state="ID" zip="00000"/>
          </ADDRESSES>
      </COVERSHEET>
    </GENERIC_ROUGHDRAFT>')
    

    我们可以定义一个xslt来将数据转换成一个html表格

    xsl <- read_xml('<?xml version="1.0" encoding="UTF-8"?>
      <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="/GENERIC_ROUGHDRAFT">
        <html>
        <table>
        <tr>
        <td>compName</td><td>dateCreated</td>
        <td>iName</td><td>type</td><td>street</td><td>state</td>
        </tr>
        <xsl:for-each select="//ADDRESS">
        <tr>
        <td><xsl:value-of select="../../../HEADER/@compName"/></td>
        <td><xsl:value-of select="../../../HEADER/@dateCreated"/></td>
        <td><xsl:value-of select="../../ESTIMATE_INFO/@iName"/></td>
        <td><xsl:value-of select="@type"/></td>
        <td><xsl:value-of select="@street"/></td>
        <td><xsl:value-of select="@state"/></td>
        </tr>
        </xsl:for-each>
        </table>
        </html>
        </xsl:template>
        </xsl:stylesheet>')
    

    我把它做成了一个 HTML 表格,这样我就可以使用 rvest::html_table 把它变成一个 data.frame。应该是这样的

    library(xslt)
    library(rvest)
    data <- xml_xslt(xml, xsl) %>% html_table(header = TRUE)  %>% .[[1]]
    #     compName dateCreated            iName     type        street state
    # 1 California  2018-08-07 Matthew Anderson Property 123 Street Cr    ID
    # 2 California  2018-08-07 Matthew Anderson     Home 123 Street Cr    ID
    

    【讨论】:

    • 谢谢,我也在找这样的东西。在您的代码中,您忘记了library(xslt)。谢谢分享。
    • @Stephan 谢谢。更新了缺失的库。
    • 未来的读者,XSLT 是一种特殊用途的声明性语言(与 XPath 同级),可以在 R 之外使用。
    • 感谢您的回复。我尝试运行您提供的内容,但遇到 xml_xslt not found 错误。
    • 另外,你会推荐使用python而不是R吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多