首页 > 解决方案 > 用于将 xml 文件转换为 xml 的 xslt 模板

问题描述

我使用 python 代码来解析多个 .xml 文件

import os
import lxml.etree as ET
import sys

inputpath = 
xsltfile = 
outpath = 

dir = []

if sys.version_info[0] >= 3:
    unicode = str

for dirpath, dirnames, filenames in os.walk(inputpath):
    structure = os.path.join(outpath, dirpath[len(inputpath):])
    if not os.path.isdir(structure):
        os.mkdir(structure)
    for filename in filenames:
        if filename.endswith(('.xml')):
            dir = os.path.join(dirpath, filename)
            print(dir)
            dom = ET.parse(dir)
            xslt = ET.parse(xsltfile)
            transform = ET.XSLT(xslt)
            newdom = transform(dom)
            infile = unicode((ET.tostring(newdom, pretty_print=True,xml_declaration=True,standalone='yes')))
            outfile = open(structure + "\\" + filename, 'a')
            outfile.write(infile)

我确实有一个 .xslt 模板,用于对同一文件中的 uuid 进行排序。

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

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

<xsl:template match="uuids">
    <xsl:copy>
        <xsl:apply-templates select="uuid">
            <xsl:sort select="."/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

所需的输出应与源 unicode char 相同,但 sortig uuid 位于同一文件中。我看到 uuid 的排序很好,但是这个 unicode 正在更改为我不想更改的数字。一世

标签: pythonxmlxsltunicodeutf-8

解决方案


在提出问题时,最好提供一个可重现的最小示例,即 XML/XSLT 对。

请尝试以下概念示例。

我正在使用 SAXON 9.7.0.15

很可能是最后一行 Python 导致了这个问题:

outfile.write(ET.tostring(newdom,pretty_print=True,xml_declaration=True,standalone='yes').decode())

请尝试 Python 的最后几行,如下所示:

import sys
if sys.version_info[0] >= 3:
    unicode = str
...
newdom = transform(dom)
infile = unicode((ET.tostring(newdom, pretty_print=True)))
outfile = open(structure + "\\" + filename, 'a')
outfile.write(infile, encoding='utf-8', xml_declaration=True, pretty_print=True)

https://lxml.de/api/lxml.etree._ElementTree-class.html#write

参考链接:如何在 Python 中使用 XSLT 转换 XML 文件

输入 XML

<?xml version="1.0" encoding="UTF-8"?>
<a:ruleInputTestConfigs xmlns:a="URI">
    <a:value xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:type="xsd:string">あいうえお@domain.com</a:value>
    <a:nameRef>email</a:nameRef>
    <a:id>1</a:id>
</a:ruleInputTestConfigs>

XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" standalone="yes"/>
    <xsl:strip-space elements="*"/>

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

输出 XML

<?xml version="1.0" encoding="UTF-8"?>
<a:ruleInputTestConfigs xmlns:a="URI">
    <a:value xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="xsd:string"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">あいうえお@domain.com</a:value>
    <a:nameRef>email</a:nameRef>
    <a:id>1</a:id>
</a:ruleInputTestConfigs>

推荐阅读