基于Python lxml的XSL转换不起作用

时间:2018-01-09 13:43:34

标签: python xml xslt lxml

使用lxml库执行从XML文件到制表符分隔文件的XSL转换时出现问题。

首先关于它转变的内容。我正在改变稍微修改过的Qt翻译文件,root是 TS ,一些上下文,每个上下文都包含许多消息,其中包含值来源翻译是必需的, translatorcomment 是可选的

<TS version="2.1" language="ru_RU">
<context>
    <message>
        <source>TextLabel1</source>
        <translatorcomment>Some comment</translatorcomment>
        <translation>Перевод TextLabel1</translation>
    </message>
    <message>
        <source>TextLabel2</source>
        <translation>Перевод TextLabel2</translation>
    </message>
</context>
<context>
    <message>
    ...
    </message>
</context>
</TS>

现在它如何变换。我需要两个转换,简单的HTML表格和tab-delimeted文件,在Excel中打开(对于Tech作者来说真的很容易)

对于HTML表格来说,这是一项非常简单,非常常见的任务(注意如何解决可选字段,或许存在更优雅的方式)。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  <xsl:template match="TS">
    <table align="left" style="font-family:arial;font-size:12px" border="2">
      <!-- Table header -->
      <tr>
        <th>Source</th>
        <th>Translation</th>
        <th>Comment</th>
      </tr>
      <!-- Iterate over context/message -->
      <xsl:for-each select="context">
        <xsl:for-each select="message">
          <tr>
            <!-- One row cells -->
            <td align="left">
              <xsl:value-of select="source" />
            </td>
            <td align="left">
              <xsl:value-of select="translation" />
            </td>
            <!-- Third, conditional cell -->
            <xsl:if test="translatorcomment">
              <td align="left">
                <xsl:value-of select="translatorcomment" />
              </td>
            </xsl:if>
            <xsl:if test="not(translatorcomment)">
              <td></td>
            </xsl:if>
          </tr>
        </xsl:for-each>
      </xsl:for-each>
    </table>
  </xsl:template>
</xsl:stylesheet>

对于tab-delimeted文件,它有点复杂。更改的输出方法是文本。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output method="text" encoding="UTF-8" indent="yes"/>
  <xsl:template match="TS">
    <!-- Header. Put tab after every value -->
    <xsl:text>Source&#x9;</xsl:text>
    <xsl:text>Translation&#x9;</xsl:text>
    <xsl:text>Comment&#x9;</xsl:text>
    <!-- End of line -->
    <xsl:text>&#10;</xsl:text>
    <!-- Iterate over values -->
    <xsl:for-each select="context">
      <xsl:for-each select="message">
        <xsl:value-of select="source" />
        <xsl:text>&#x9;</xsl:text>
        <xsl:value-of select="translation" />
        <xsl:text>&#x9;</xsl:text>
        <xsl:if test="translatorcomment">
          <xsl:value-of select="translatorcomment" />
          <xsl:text>&#x9;</xsl:text>
        </xsl:if>
        <xsl:if test="not(translatorcomment)">
          <xsl:text>&#x9;</xsl:text>
        </xsl:if>
        <!-- End of line -->
        <xsl:text>&#10;</xsl:text>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

我怎么知道他们两个都在工作?我在Free Online XSL transformer上查看了它,两者都提供了完全正确的结果。是的,首先我写了转换,然后开始看看如何离线执行它们,这似乎并不容易。我们使用的是C ++和Python,Python似乎是最简单的方法,因为它有很多库,不需要编译等。

现在,如果你没有失去耐心,关于我的问题和我使用的Python代码。 我正在使用最常用的转换工具,lxml,方法在这里讨论了很多次

    import lxml.etree as et

    xml_file = et.parse(input_xml)
    xslt_file = et.parse(transform_xsl)
    transform = et.XSLT(xslt_file)
    transformed = transform(xml_file)
    with open(self.output, "w") as out_file:
        print((et.tostring(transformed, pretty_print=True)).decode("utf-8"), file=out_file)

我正在执行我的第一次HTML转换而没有任何问题。第二个转换为制表符分隔文件,但LXML

除外
Traceback (most recent call last):
  File "xsl_transform.py", line 137, in <module>
    sys.exit(main())
  File "xsl_transform.py", line 127, in main
    xsl_transformer.transform()
  File "xsl_transform.py", line 86, in transform
    print((et.tostring(transformed, pretty_print=True)).decode("utf-8"), file=out_file)
AttributeError: 'NoneType' object has no attribute 'decode'

显然,尝试转换为字符串时,lxml.etree._XSLTResultTree类型返回None。其他尝试,print(str(transformed))也因错误UnicodeEncodeError: 'charmap' codec can't encode character '\xab' in position 17440: character maps to <undefined>

而失败

因此,transformed包含一些内容,但无法转换为字符串。即使所有文件都是UTF-8

,也许编码有问题

0 个答案:

没有答案