pandas 将文本中带有嵌入节点的XML解析为DataFrame

7kjnsjlb  于 2023-02-20  发布在  其他
关注(0)|答案(1)|浏览(169)

我有这样一个XML:

<root>
    <epig>
    string1
    <tit>string2</tit>
    string3
    </epig>
</root>

我正在尝试建立一个数据框架与以下内容:

dftext = pd.read_xml("filename.xml", xpath='root/epig')

在 Dataframe 中返回包含string1的列epig和包含string2的列tit,但是string3在 Dataframe 中消失了,这是当前输出:
| 埃皮格|山雀|
| - ------|- ------|
| 字符串1|字符串2|
Dataframe 输出应为:
| 埃皮格|山雀|
| - ------|- ------|
| 字符串1+字符串3|串2|
我错在哪里?

ddrv8njm

ddrv8njm1#

在XML中,<epig>元素下有三个节点:两个<text>节点和一个<tit>节点。为了检索后一个文本节点,在Python的etree库中,你必须使用tit元素上的**.tail**属性。在Pandas中,read_xml(设计用于解析平面而不是所有XML类型的方便方法)只解析第一个文本节点,因为它不遍历多个文本节点。
对于这种多文本节点的特殊用例,考虑使用XSLT重新设置XML的样式,XSLT是一种专用语言,用于转换XML文件,read_xml支持使用stylesheet参数和默认lxml解析器(而不是etree解析器)。

XSLT*(保存为.xsl,一种特殊的.xml文件)*

Below将两个文本节点连接为一个新的<epig>子元素,该子元素成为<tit>的同级元素,每个子元素位于xpath中使用的新父元素<item>下。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/root">
     <xsl:copy>
       <xsl:apply-templates select="epig"/>
     </xsl:copy>
    </xsl:template>

    <xsl:template match="epig">
     <item>
       <epig>
         <xsl:value-of select="normalize-space(concat(text()[1], text()[2]))"/>
       </epig>
       <xsl:copy-of select="tit"/>
     </item>
    </xsl:template>
</xsl:stylesheet>

Online Demo

巨蟒

下面将解析XSLT扁平化输出的所有<item>节点。

dftext = pd.read_xml("filename.xml", xpath=".//item", stylesheet="style.xsl")

dftext
#               epig      tit
# 0  string1 string3  string2

相关问题