【问题标题】:XML to HTML table with XSLT with dynamic headings带有动态标题的 XSLT 的 XML 到 HTML 表
【发布时间】:2011-11-21 13:15:27
【问题描述】:

我的问题有点类似于XML to HTML table with XSLT

我有一个在 XML 中定义如下的字典:

<dictionary>
    <languages>
        <language>en</language>
        <language>ja</language>
    </languages>
    <entries>
        <entry id="1">
            <en>Test</en>
            <ja>テスト</ja>
        </entry>
        <entry id="2">
            <en>Test2</en>
            <ja>テスト2</en>
        </entry>
    </entries>
</dictionary>

我想要 XHTML 中的以下输出:

<table>
    <thead>
        <tr>
            <th>en</th>
            <th>ja</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Test</td>
            <td>テスト</td>
        </tr>
        <tr>
            <td>Test2</td>
            <td>テスト2</td>
        </tr>
    </tbody>
</table>

我将XML to HTML table with XSLT的答案改编如下:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="//dictionary/entries">
     <table><xsl:apply-templates select="entry"/></table>
 </xsl:template>

 <xsl:template match="entry[1]">
  <thead><tr><xsl:apply-templates select="*" mode="header"/></tr></thead>
  <xsl:call-template name="standardRow"/>
 </xsl:template>

 <xsl:template match="entry" name="standardRow">
  <tbody><tr><xsl:apply-templates select="*"/></tr></tbody>
 </xsl:template>

 <xsl:template match="entry/*">
  <td><xsl:apply-templates select="node()"/></td>
 </xsl:template>

 <xsl:template match="entry/*" mode="header">
  <th><xsl:value-of select="name()"/></th>
 </xsl:template>
</xsl:stylesheet>

问题是我可能有如下输入:

<dictionary>
    <languages>
        <language>en</language>
        <language>ja</language>
            <language>id</language>
    </languages>
    <entries>
        <entry id="1">
            <en>Test</en>
            <ja>テスト</ja>
        </entry>
        <entry id="2">
            <ja>テスト2</ja>
            <en>Test2</en>
            <id>uji2</id>
        </entry>
    </entries>
</dictionary>

您可能已经理解,XSLT 使用第一个entry 节点来定义列名,并且不会生成列id。此外,如果entry 中的语言顺序发生变化,&lt;td&gt; 不会按顺序出现。

有了上面的输入,我想要下面的输出:

<table>
    <thead>
        <tr>
            <th>en</th>
            <th>ja</th>
            <th>id</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Test</td>
            <td>テスト</td>
            <td></td>
        </tr>
        <tr>
            <td>Test2</td>
            <td>テスト2</td>
            <td>Uji2</td>
        </tr>
    </tbody>
</table>

这是我第一次使用 XSLT,我真的不知道该怎么做。我想我可以使用languages 节点。请注意,XML 输入格式是灵活的,即使我需要更改格式,我也欢迎任何建议。

【问题讨论】:

    标签: xslt


    【解决方案1】:

    这是一个示例样式表:

    <xsl:stylesheet
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="1.0">
    
      <xsl:output method="html" indent="yes"/>
    
      <xsl:key name="k1" match="entry/*" use="concat(generate-id(..), '|', local-name())"/>
    
      <xsl:variable name="languages" select="/dictionary/languages/language"/>
    
      <xsl:template match="dictionary">
        <xsl:apply-templates select="entries"/>
      </xsl:template>
    
      <xsl:template match="entries">
        <table>
          <thead>
            <tr>
              <xsl:apply-templates select="$languages" mode="header"/>
            </tr>
          </thead>
          <tbody>
            <xsl:apply-templates/>
          </tbody>
        </table>
      </xsl:template>
    
      <xsl:template match="language" mode="header">
        <th>
          <xsl:value-of select="."/>
        </th>
      </xsl:template>
    
      <xsl:template match="entry">
        <tr>
          <xsl:apply-templates select="$languages">
            <xsl:with-param name="entry" select="current()"/>
          </xsl:apply-templates>
        </tr>
      </xsl:template>
    
      <xsl:template match="language">
        <xsl:param name="entry"/>
        <td>
          <xsl:value-of select="key('k1', concat(generate-id($entry), '|', .))"/>      
        </td>
      </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

    • 我用这个样式表进行了测试,看起来它工作得很好。回答采纳!非常感谢你。关键在variablekey,我没有怎么用。
    • 解决方案的关键是确保每次要输出entry 的数据时都处理$languages,然后将entry 作为参数传入。使用xsl:keykey 函数是为了提高效率,您也可以使用&lt;xsl:value-of select="$entry/*[local-name() = current()]"/&gt; 代替&lt;xsl:value-of select="key('k1', concat(generate-id($entry), '|', .))"/&gt;
    猜你喜欢
    • 1970-01-01
    • 2012-03-19
    • 2023-03-21
    • 2015-01-24
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    • 2013-02-16
    相关资源
    最近更新 更多