【问题标题】:Convert XML to HTML using xslt使用 xslt 将 XML 转换为 HTML
【发布时间】:2012-09-29 13:43:36
【问题描述】:

我开发了一个基于 java 的命令行实用程序,可以将 xml 转换为另一个 xml 文件并生成 HTML。在这个程序中,我使用 SAX 解析器将源 xml 的内容读入我的 java 对象,然后使用 JAXB 生成 XML。现在我正在通过填充 HTML 内容的字符串来创建 HTMl 文件,但它会在我的 java 类中产生硬编码的 html 代码。根据我的研究,我可以使用 XSLT 将 XML 转换为 HTML。我是 XSLT 的新手。谁能帮我?请参阅下面的示例。谢谢

XML 输入:

<Groups>
   <Group>
    <GroupName>GroupA</GroupName>
    <Role>
        <RoleName>Correspondence Team B</RoleName>
        <Functions>
            <Function>CT2 Work</Function>
            <Function>HOL01_My Work</Function>
            <Function>HOL02_My Work</Function>
        </Functions>
    </Role>
</Group>

 <GroupName>GroupB</GroupName>
    <Role>
        <RoleName>Customer Service Rep</RoleName>
        <Functions>
            <Function>CSR Work</Function>
            <Function>HOL01_My Work</Function>
        </Functions>
    </Role>
</Group>
<Group>
    <GroupName>GroupB</GroupName>
    <Role>
        <RoleName>Dispute Advisor</RoleName>
        <Functions>
            <Function>DA Work</Function>
            <Function>HOL01_My Work</Function>
        </Functions>
    </Role>
</Group>
<Group>
    <GroupName>GroupA</GroupName>
    <Role>
        <RoleName>Correspondence Team</RoleName>
        <Functions>
            <Function>CT Work</Function>
            <Function>HOL01_My Work</Function>
        </Functions>
    </Role>
</Group>

<Group>
    <GroupName>GroupB</GroupName>
    <Role>
        <RoleName>Correspondence Team B</RoleName>
        <Functions>
            <Function>CT2 Work</Function>
            <Function>HOL01_My Work</Function>
            <Function>HOL02_My Work</Function>
        </Functions>
    </Role>
</Group>

所需的 Html 表格格式:

<table border=1>
    <tr>
        <th>Group Name</th>
        <th>Role Name</th>
        <th>Function Names</th>
    </tr>
    <tr>
        <td rowspan=5>Group A</td>
        <td rowspan=2>Correspondence Team</td>
        <td>CT Work</td>
    </tr>
    <tr>
        <td>HOL01_My Work</td>
    </tr>
    <tr>
        <td rowspan=3>Correspondence Team B</td>
        <td>CT Work</td>
    </tr>
    <tr>
        <td>HOL01_My Work</td>
    </tr>
    <tr>
        <td>HOL01_My Work</td>
    </tr>
    <tr>
        <td rowspan=0>Group B</td>
        <td rowspan=2>Customer Service Rep</td>
        <td>CSR Work</td>
    </tr>
    <tr>
        <td>HOL01_My Work</td>
    </tr>
    <tr>
        <td rowspan=2>Dispute Advisor</td>
        <td>DA Work</td>
    </tr>
    <tr>
        <td>HOL01_My Work</td>
    </tr>
    <tr>
        <td rowspan=2>Correspondence Team</td>
        <td>CT Work</td>
    </tr>
    <tr>
        <td>HOL01_My Work</td>
    </tr>
</table>

【问题讨论】:

  • "谁能帮帮我?" - 什么?请更具体。
  • 这在我看来像是一个分组问题,现在最好用 XSLT 2.0 和 Saxon 9 (saxon.sourceforge.net/#F9.4HE) 来解决。您是否能够或愿意使用 XSLT 2.0?还是您想使用作为 Sun/Oracle JRE 一部分的 XSLT 1.0 处理器?

标签: xml xslt


【解决方案1】:

假设 XSLT 2.0(您可以在 Saxon 9 的帮助下使用 Java 运行)您可以使用类似的样式表

<xsl:stylesheet 
  version="2.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="html" indent="yes" version="5.0"/>

<xsl:template match="/">
  <html lang="en">
    <head>
      <title>Test</title>
    </head>
    <body>
      <h1>Test</h1>
      <xsl:apply-templates/>
    </body>
  </html>
</xsl:template>


<xsl:template match="Groups">
  <table frame="border" rules="all">
    <thead>
      <th>Group Name</th>
      <th>Role Name</th>
      <th>Function Names</th>
    </thead>
    <tbody>
      <xsl:variable name="groups" as="element(group)*">
        <xsl:for-each-group select="Group" group-by="GroupName">
          <group name="{current-grouping-key()}" size="{count(current-group()/Role/Functions/Function)}">
            <xsl:for-each-group select="current-group()" group-by="Role/RoleName">
              <role name="{current-grouping-key()}" size="{count(current-group()/Role/Functions/Function)}">
                <xsl:copy-of select="current-group()/Role/Functions/Function"/>
              </role>
            </xsl:for-each-group>
          </group>
        </xsl:for-each-group>
      </xsl:variable>
      <xsl:apply-templates select="$groups/role/Function"/>
    </tbody>
  </table>
</xsl:template>

<xsl:template match="group/role/Function">
  <tr>
    <xsl:apply-templates select="." mode="group"/>
    <xsl:apply-templates select="." mode="role"/>
    <td>
      <xsl:value-of select="."/>
    </td>
  </tr>
</xsl:template>

<xsl:template match="group/role[1]/Function[1]" mode="group">
  <th rowspan="{../../@size}">
    <xsl:value-of select="../../@name"/>
  </th>
</xsl:template>

<xsl:template match="group/role[position() gt 1]/Function |
                     group/role[1]/Function[position() gt 1]" mode="group"/>

<xsl:template match="group/role/Function[1]" mode="role">
  <th rowspan="{../@size}">
    <xsl:value-of select="../@name"/>
  </th>
</xsl:template>

<xsl:template match="group/role/Function[position() gt 1]" mode="role"/>

</xsl:stylesheet>

一样转换输入文档
<Groups>
   <Group>
    <GroupName>GroupA</GroupName>
    <Role>
        <RoleName>Correspondence Team B</RoleName>
        <Functions>
            <Function>CT2 Work</Function>
            <Function>HOL01_My Work</Function>
            <Function>HOL02_My Work</Function>
        </Functions>
    </Role>
</Group>

<Group>
 <GroupName>GroupB</GroupName>
    <Role>
        <RoleName>Customer Service Rep</RoleName>
        <Functions>
            <Function>CSR Work</Function>
            <Function>HOL01_My Work</Function>
        </Functions>
    </Role>
</Group>
<Group>
    <GroupName>GroupB</GroupName>
    <Role>
        <RoleName>Dispute Advisor</RoleName>
        <Functions>
            <Function>DA Work</Function>
            <Function>HOL01_My Work</Function>
        </Functions>
    </Role>
</Group>
<Group>
    <GroupName>GroupA</GroupName>
    <Role>
        <RoleName>Correspondence Team</RoleName>
        <Functions>
            <Function>CT Work</Function>
            <Function>HOL01_My Work</Function>
        </Functions>
    </Role>
</Group>

<Group>
    <GroupName>GroupB</GroupName>
    <Role>
        <RoleName>Correspondence Team B</RoleName>
        <Functions>
            <Function>CT2 Work</Function>
            <Function>HOL01_My Work</Function>
            <Function>HOL02_My Work</Function>
        </Functions>
    </Role>
</Group>
</Groups>

像 HTML5 一样

<!DOCTYPE HTML>
<html lang="en">
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Test</title>
   </head>
   <body>
      <h1>Test</h1>
      <table frame="border" rules="all">
         <thead>
            <th>Group Name</th>
            <th>Role Name</th>
            <th>Function Names</th>
         </thead>
         <tbody>
            <tr>
               <th rowspan="5">GroupA</th>
               <th rowspan="3">Correspondence Team B</th>
               <td>CT2 Work</td>
            </tr>
            <tr>
               <td>HOL01_My Work</td>
            </tr>
            <tr>
               <td>HOL02_My Work</td>
            </tr>
            <tr>
               <th rowspan="2">Correspondence Team</th>
               <td>CT Work</td>
            </tr>
            <tr>
               <td>HOL01_My Work</td>
            </tr>
            <tr>
               <th rowspan="7">GroupB</th>
               <th rowspan="2">Customer Service Rep</th>
               <td>CSR Work</td>
            </tr>
            <tr>
               <td>HOL01_My Work</td>
            </tr>
            <tr>
               <th rowspan="2">Dispute Advisor</th>
               <td>DA Work</td>
            </tr>
            <tr>
               <td>HOL01_My Work</td>
            </tr>
            <tr>
               <th rowspan="3">Correspondence Team B</th>
               <td>CT2 Work</td>
            </tr>
            <tr>
               <td>HOL01_My Work</td>
            </tr>
            <tr>
               <td>HOL02_My Work</td>
            </tr>
         </tbody>
      </table>
   </body>
</html>

【讨论】:

  • 谢谢大家的回复。这是伟大的马丁。我试过你的代码。起初,它抛出错误...“net.sf.saxon.trans.XPathException:Unsupported HTML version: 5.0”...我刚刚从您的代码中删除了 xsl:output 元素中的 HTML 版本规范,它作品。我了解到这个错误只发生在 Saxon9 而不是在以前的版本中。非常感谢。
  • 我用 Saxon 9.4 HE Java 测试了那个样式表,没有出现任何错误,所以我很惊讶你说你得到了那个错误。但你是对的,样式表输出 HTML 不需要 HTML 版本。
  • 确切地说,我使用的是 SaxonHE 9.4.0.6,我收到了这个错误。所以它并没有出现在所有 Saxon 9 中。感谢添加的信息。
  • @MartinHonnen:你能看看stackoverflow.com/questions/30662205/…
猜你喜欢
  • 2014-03-08
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 2016-08-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多