pandas read_xml 缺失数据

pandas read_xml missing data

我试过使用 Pandas read_xml 并且它可以很好地读取 XML 的大部分内容,但它遗漏了一些部分,因为它的格式略有不同。我在下面包含了一个摘录,它显示“类型”、“激活”很好,但不适用于“Amt”值。它选择标题为“Amt”的列,而不是值。任何人都可以指出我如何阅读它的正确方向。谢谢

<Type>PYI</Type>
<Activation>N</Activation>
<Amt val="4000" curr="GBP"/>

xml_df = pd.read_xml(xml_data)

任何人都可以提供帮助我已经尝试阅读 Pandas.read_xml 的文档,但我明白为什么它不接受这个?

默认情况下,pandas.read_xml 解析一组节点的所有 直接 后代,包括其子节点和属性。除非 xpath 论点表明了这一点,否则 read_xml 不会比 直接 后代更进一步。

为了说明您的用例。下面可能是 XML 的一般设置,其中解析了 <Type> 及其兄弟 <Activation><Amt>。但是,<Amt> 不包含文本节点,仅包含属性。因此该列中的值应该为空。

<root>
  <row>
    <Type>PYI</Type>              <!-- Type IS A CHILD NODE OF row -->
    <Activation>N</Activation>    <!-- Activation IS A CHILD NODE OF row -->
    <Amt val="4000" curr="GBP"/>  <!-- Amt IS A CHILD NODE OF row -->
  </row>
</root>

但是你问,为什么 read_xml 忽略 valcurr 属性?因为每个都不是 <row> 直接 后代。他们是 <Amt> 的后代(即 <row> 的孙辈)。如果属性被移动到 <row>,那么它们将被捕获,如下所示:

<root>
  <row val="4000" curr="GBP">     <!-- val AND curr ARE CHILD ATTRIBS OF row -->
    <Type>PYI</Type>              <!-- Type IS A CHILD NODE OF row -->
    <Activation>N</Activation>    <!-- Activation IS A CHILD NODE OF row -->
    <Amt/>                        <!-- Amt IS A CHILD NODE OF row -->
  </row>
</root>

要捕获这些属性,请调整 xpath 参数以指向其直接父级:

amt_df = pd.read_xml("Input.xml", xpath="//Amt")

要使用 <row> 级别信息捕获此类属性,请考虑使用专用语言 XSLT,将您的原始 XML 转换为以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <row>
      <Type>PYI</Type>
      <Activation>N</Activation>
      <Amt_val>4000</Amt_val>
      <Amt_curr>GBP</Amt_curr>
   </row>
</root>

以上是使用 stylesheet 参数时 read_xml 解析的中间输出,如下所示:

xsl = '''<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>
  
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
    <xsl:template match="row">
    <xsl:copy>
      <xsl:copy-of select="*[name() != 'Amt']"/>
      <Amt_val><xsl:value-of select="Amt/@val"/></Amt_val>
      <Amt_curr><xsl:value-of select="Amt/@curr"/></Amt_curr>
    </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>'''

row_df = pd.read_xml("Input.xml", xpath="//row", stylesheet=xsl")