1

(我已经广泛研究了这个问题,但还没有找到合适的解决方案。)

我正在使用 XSLT 将一系列 XML 文件转换为类似“树”的 HTML 文档,其中元素之间的父子关系通过缩进反映出来。

下面的解决方案工作正常,但它太冗长,我们还需要适应将来向模式中添加一些新元素。

有什么好的通用解决方案可以满足我们的需要?我在网上看到了递归解决方案,其中使用“深度”变量并递增并作为参数传入,并用于驱动缩进级别;这似乎是一种常见的模式,但我无法让它为我工作。

谢谢。

所以我的数据文件如下所示:

<document>
  <metadata>
    <version>1.0</version>
    <date>1/1/12</date>
    etc...
  </metadata>
  <trackdata>
    <tracks>
      <track>123</track>
      <track>456</track>
      etc...
  </trackdata>
</document>

和 XSLT(注意不同级别的文本缩进的不同值):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="no"/>
    <xsl:template match="@*|node()">
        <xsl:apply-templates select="@*|node()" />
    </xsl:template>

        <xsl:template match="metadata">
            Metadata: <xsl:apply-templates/>
        </xsl:template>

        <xsl:template match="version">
          <div style="text-indent:3em">Version: <xsl:value-of select="text()"/></div>
        </xsl:template>

        <xsl:template match="date">
          <div style="text-indent:3em">Date: <xsl:value-of select="text()"/></div>
        </xsl:template>

        <xsl:template match="trackdata">
          Track Data: <xsl:value-of select="text()"/></div>
        </xsl:template>

        <xsl:template match="tracks">
            <div style="text-indent:3em">Tracks: <xsl:apply-templates/>
        </xsl:template>

        <xsl:template match="track">
          <div style="text-indent:6em">Track: <xsl:value-of select="text()"/></div>
        </xsl:template>

ETC...

4

1 回答 1

2

尝试创建一个变量来保存该text-indent值。像这样的东西:

  <xsl:template match="version">
    <xsl:variable name="vIndent" select="count(ancestor::*) * 3"/>    
    <div style="text-indent:{$vIndent}em">Version: <xsl:value-of select="text()"/></div>
  </xsl:template>

这是另一个完整的用法示例...

XML 输入(格式正确)

<document>
  <metadata>
    <version>1.0</version>
    <date>1/1/12</date>
  </metadata>
  <trackdata>
    <tracks>
      <track>123</track>
      <track>456</track>
    </tracks>
  </trackdata>
</document>

XSLT 1.0

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

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

  <xsl:template match="/">
    <html>
      <xsl:apply-templates/>
    </html>
  </xsl:template>

  <xsl:template match="*">
    <xsl:variable name="vIndent" select="count(ancestor::*) * 3"/>
    <div style="text-indent:{$vIndent}em"><xsl:value-of select="name()"/>: <xsl:apply-templates/></div>
  </xsl:template>

  <xsl:template match="document">
    <xsl:apply-templates/>
  </xsl:template>  

</xsl:stylesheet>

原始 HTML 输出

<html>
   <div style="text-indent:3em">metadata: 
      <div style="text-indent:6em">version: 1.0</div>
      <div style="text-indent:6em">date: 1/1/12</div>
   </div>
   <div style="text-indent:3em">trackdata: 
      <div style="text-indent:6em">tracks: 
         <div style="text-indent:9em">track: 123</div>
         <div style="text-indent:9em">track: 456</div>
      </div>
   </div>
</html>

如果您希望第一个 div 没有缩进,您可以将变量更改为:

<xsl:variable name="vIndent" select="(count(ancestor::*) * 3) - 3"/>
于 2012-05-14T15:57:30.783 回答