我可以使用python根据csv文件值编辑xml文件吗?

时间:2018-03-28 20:18:41

标签: python xml csv

我有一个CSV文件,其中包含数字列表,其中包含空白,例如:

0001
0002
0003
0005
0007
etc.

我有一个带有标识符的节点的XML文件,其中包含一个没有间隙的数字列表,例如:

<?xml version='1.0' encoding='utf-8'?>
<root>
    <item>
        <unitd>0001</unitd>
        <unittitle>description of item 1</unittitle>
    </item>
    <item>
        <unitd>0002</unitd>
        <unittitle>description of item 2</unittitle>
    </item>
    <item>
        <unitd>0003</unitd>
        <unittitle>description of item 3</unittitle>
    </item>
    <item>
        <unitd>0004</unitd>
        <unittitle>description of item 4</unittitle>
    </item>
    <item>
        <unitd>0005</unitd>
        <unittitle>description of item 5</unittitle>
    </item>
    <item>
        <unitd>0006</unitd>
        <unittitle>description of item 6</unittitle>
    </item>
    <item>
        <unitd>0007</unitd>
        <unittitle>description of item 7</unittitle>
    </item>
</root>      <!-- added by edit -->

我想在XML文件的项目中添加一个额外元素,这些元素具有可在CSV文件中找到的标识符,如下所示:

<root>
<item>
    <unitd>0001</unitd>
    <unittitle>description of item 1</unittitle>
    <link>link to extra info on item 1</link>
</item>
<item>
    <unitd>0002</unitd>
    <unittitle>description of item 2</unittitle>
    <link>link to extra info on item 2</link>
</item>
<item>
    <unitd>0003</unitd>
    <unittitle>description of item 3</unittitle>
    <link>link to extra info on item 3</link>
</item>
<item>
    <unitd>0004</unitd>
    <unittitle>description of item 4</unittitle>
</item>
<item>
    <unitd>0005</unitd>
    <unittitle>description of item 5</unittitle>
    <link>link to extra info on item 5</link>
</item>
<item>
    <unitd>0006</unitd>
    <unittitle>description of item 6</unittitle>
</item>
<item>
    <unitd>0007</unitd>
    <unittitle>description of item 7</unittitle>
    <link>link to extra info on item 7</link>
</item>

我可以使用python执行此操作吗?如何或有更聪明的方法来处理此问题?

1 个答案:

答案 0 :(得分:0)

处理XML到XML转换的最明智的方法是使用专为这个目的而设计的XSLT

因此,要将源XML转换为所需的目标XML,可以使用此XSLT-1.0脚本(名为trans.xslt):

<xsl:stylesheet version ="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" encoding="UTF-8"/>
    <xsl:variable name="additional" select="document('a_link.xml')/LinkMapping" />   <!-- name of helper XML file -->

    <!-- identity template -->
    <xsl:template match="node()|@*" > 
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template> 

    <!-- item transform template -->
    <xsl:template match="item" > 
        <xsl:copy>
            <xsl:copy-of select="node()|@*" />
            <xsl:if test="$additional/map[@id=current()/unitd]">
                <link>
                    <xsl:value-of select="$additional/map[@id=current()/unitd]/text()" />
                </link>
            </xsl:if>
        </xsl:copy>
    </xsl:template> 

</xsl:stylesheet>

此模板需要一个额外的XML文件,其中包含名为link的CSV文件中a_link.xml的映射。你的CSV文件示例没有显示任何这样的关系,但将CSV转换为类似下面的格式应该没问题。

<LinkMapping>
    <map id="0001">link to extra info on item 1</map>
    <map id="0002">link to extra info on item 2</map>
    <map id="0003">link to extra info on item 3</map>
    <map id="0005">link to extra info on item 5</map>
    <map id="0007">link to extra info on item 7</map>
</LinkMapping>

将上述XSLT与XML帮助文件一起应用的输出是所希望的。

因此,要在Python中使用它,您可以参考to this SO answer,它解释了如何使用XSLT转换XML文件。

假设您的XML文件名为input.xml,代码可能如下所示:

import lxml.etree as ET

dom = ET.parse("input.xml")
xslt = ET.parse("trans.xslt")
transform = ET.XSLT(xslt)
newdom = transform(dom)
print(ET.tostring(newdom, pretty_print=True))

现在你应该得到你想要的结果。