【问题标题】:Combining information and handling namespaces in huge XML-file在巨大的 XML 文件中组合信息和处理名称空间
【发布时间】:2021-05-16 05:16:19
【问题描述】:

我有一个巨大的 (85GB) XML 文件,其中包含有关丹麦汽车的各种数据,我需要从中提取一些数据(不是全部)。实际文件中有更多信息,但此处提供了该文件的示例(粗略翻译)。

<?xml version="1.0" encoding="UTF-8"?>
<ns:ESStatistikListeModtag_I xmlns:ns="http://skat.dk/dmr/2007/05/31/">
  <ns:Statistic>
    <ns:VehicleType>Personbil</ns:VehicleType>
    <ns:RegNo>XX12345</ns:RegNo>
    <ns:VehicleInfo>
      <ns:VehicleMake>AUDI</ns:VehicleMake>
      <ns:VehicleModel>Q7</ns:VehicleModel>
    </ns:VehicleInfo>
    <ns:VehicleInspection>
      <ns:InspectionDate>2000-05-31+02:00</ns:InspectionDate>
      <ns:InspectionResult>Approved</ns:InspectionResult>
    </ns:VehicleInspection>
  </ns:Statistic>
  <ns:Statistic>
    <ns:VehicleType>Personbil</ns:VehicleType>
    <ns:RegNo>YY54321</ns:RegNo>
    <ns:VehicleInfo>
      <ns:VehicleMake>RENAULT</ns:VehicleMake>
      <ns:VehicleModel>CLIO</ns:VehicleModel>
    </ns:VehicleInfo>
    <ns:VehicleInspection>
      <ns:InspectionDate>2008-11-31+02:00</ns:InspectionDate>
      <ns:InspectionResult>Approved</ns:InspectionResult>
      <ns:InspectionKm>310</ns:InspectionKm>
    </ns:VehicleInspection>
  </ns:Statistic>
  <ns:Statistic>
    <ns:VehicleType>Van</ns:VehicleType>
    <ns:RegNo>QQ78901</ns:RegNo>
    <ns:VehicleInfo>
      <ns:VehicleMake>AUDI</ns:VehicleMake>
      <ns:VehicleModel>Q3</ns:VehicleModel>
    </ns:VehicleInfo>
    <ns:VehicleInspection>
      <ns:InspectionDate>2010-10-08+02:00</ns:InspectionDate>
      <ns:InspectionResult>Approved</ns:InspectionResult>
      <ns:InspectionKm>78</ns:InspectionKm>
    </ns:VehicleInspection>
  </ns:Statistic>
</ns:ESStatistikListeModtag_I>

我已经查看了各种问题,但我有限的 XML 技能使得处理所有节点前面的名称空间变得困难。我特别关注了 Martin Morgan 在Combine values in huge XML-files 提供的答案。

我想要的是 - 对于值为 InspectionKm 的条目 - 提取注册号 (RegNo) 作为 id,然后提取车辆制造商 (VehicleMake) 和检查公里数 (InspectionKm) 的值。

谁能解释我如何使用 xmlEventParse 来提取相关信息?

【问题讨论】:

    标签: r xml xml-parsing


    【解决方案1】:

    我不了解 xmlEventParse,但如果您准备考虑不同的技术,您可以在流式 XSLT 3.0 转换中这样做:

    <xsl:transform version="3.0" 
                   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                   xpath-default-namespace="http://skat.dk/dmr/2007/05/31/">
    <xsl:mode streamable="yes" on-no-match="shallow-skip"/>
    <xsl:template match="Statistic" >
      <xsl:variable name="this" select="copy-of(.)"/>
      <xsl:if test="exists($this//InspectionKm)">
        <out make="{$this/VehicleInfo/VehicleMake}" km="{$this//InspectionKm}"/>
      </xsl:if>
    </xsl:template>
    </xsl:transform>
    

    作为第一个猜测,我预计需要一个小时左右。

    【讨论】:

      【解决方案2】:

      这是我使用 xml2 包的方法。当然,鉴于文件的大小,我不确定您可能会遇到哪些性能/内存限制。

      library(xml2)
      library(dplyr)
      
      #get namespace
      ns<-xml_ns(file)
      
      #find parent nodes which contain all requested information
      statistic <-xml_find_all(file, ".//ns:Statistic", ns) 
      
      #get  request information from each node
      regno <- xml_find_first(statistic, ".//ns:RegNo") %>% xml_text()
      make <- xml_find_first(statistic, ".//ns:VehicleMake") %>% xml_text()
      km <- xml_find_first(statistic, ".//ns:InspectionKm") %>% xml_text()
      
      #merge into a final dataframe
      
      answer <- data.frame(regno, make, km)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-03
        • 1970-01-01
        • 2018-06-11
        相关资源
        最近更新 更多