重新订购用于HTML打印的XML

时间:2018-03-21 11:33:26

标签: python html xml python-2.7 xslt

我正在使用Python 2.7将XML响应(从REST调用转换为Atlassian Fisheye)转换为HTML表格。

XML数据方便地以“行”元素呈现,并且还包括相关的“标题”。而且,现在,我可以生成一个外观漂亮的表,除了标题行最后打印,因为标题是在XML文档的末尾指定的。

确保自己处于最顶端的最简单方法是什么?我可以使用XSLT执行此操作,还是需要先将XML文档操作才能将其转换为HTML?如果是后者,那么重新排序XML元素的最简单/最简单的方法是什么?

我用来将XML转换为HTML的代码是:

from lxml import etree

def xml_to_html(text):
  source = etree.fromstring(text)

  xslt_doc = etree.parse("change-report.xslt")
  xslt_transformer = etree.XSLT(xslt_doc)

  output_doc = xslt_transformer(source)
  print(str(output_doc))
  output_doc.write("change-report.html", pretty_print=True)

我使用的XSLT看起来像这样:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <html>
      <body>
        <table><xsl:apply-templates/></table>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="headings">
    <tr><xsl:apply-templates select="heading"/></tr>
  </xsl:template>
  <xsl:template match="heading">
    <th><xsl:value-of select="."/></th>
  </xsl:template>
  <xsl:template match="row">
    <tr><xsl:apply-templates select="item"/></tr>
  </xsl:template>
  <xsl:template match="item">
    <td><xsl:value-of select="."/></td>
  </xsl:template>
</xsl:stylesheet>

输入XML(由Fisheye的REST API返回)如下所示:

<?xml version="1.0" ?>
<tabularQueryResult>
  <row>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">167</item>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">trunk/build.gradle</item>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">ABC-1835 Include RPM building code</item>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">u4538</item>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">2018-03-13T11:43:15Z</item>
  </row>
  <row>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">166</item>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">trunk/settings.gradle</item>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">ABC-1863 Added new subproject.</item>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">a2345</item>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">2018-03-06T13:31:15Z</item>
  </row>
  <row>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">165</item>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">trunk/build.gradle</item>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">ABC-1826 Refactoring.</item>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">u4538</item>
    <item xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">2018-02-28T10:56:15Z</item>
  </row>
  <headings>
    <heading>csid</heading>
    <heading>path</heading>
    <heading>comment</heading>
    <heading>author</heading>
    <heading>date</heading>
  </headings>
</tabularQueryResult>

1 个答案:

答案 0 :(得分:1)

您的XSLT中没有匹配tabularQueryResult的模板,这意味着built-in template rules将适用。这将只按文档顺序选择tabularQueryResult的子节点。由于headings位于输入XML中的row之后,它们最后出现。 (在模板匹配headings之前,您有一个匹配rows的模板的事实确实没有任何区别。)

要解决此问题,只需为tabularQueryResult添加模板,然后明确选择所需的顺序。

<xsl:template match="tabularQueryResult">
  <xsl:apply-templates select="headings" />
  <xsl:apply-templates select="row" />
</xsl:template>