为同一个XSL样式表使用不同的HTML模板

zig*_*ggy 3 html java xslt velocity xalan

是否可以为同一个XSLT样式表使用不同的HTML布局?

我一直在阅读XSLT,我看到的大多数示例都表明HTML代码实际上是嵌入在样式表中的.

是否可以将相同的样式表用于多个HTML布局?(我的想法类似于Velocity的工作原理 - 即可以使用相同的Velocity标签处理多个HTML文件).

我正在使用Java Xalan处理器来处理XSLT.

编辑

我在下面尝试过@Dimitre Novatchev方法,它完美无缺.唯一的问题是我如何处理循环元素?例如,如果将xml文档修改为:

<person>
 <fname>John</fname>
 <lname>Smith</lname>
 <age>25</age>
 <age>33</age>
 <age>55</age>
</person>
Run Code Online (Sandbox Code Playgroud)

我如何遍历每个年龄元素?

这是我在HTML模板上尝试但我没有看到任何区别:

<html xmlns:gen="my:tranform-generated">
 <body>
  <h1>Hi <gen:fname/> <gen:lname/>!</h1>

  You are <gen:age/> years old.  

  <gen:for-each select="/person/age">
    <gen:age/>,
  </gen:for-each>

 </body>
</html>
Run Code Online (Sandbox Code Playgroud)

预期产出

我想要上面的输出

Hi JohnSmith!
You are 25 years old. 

25, 33, 55
Run Code Online (Sandbox Code Playgroud)

Dim*_*hev 6

是的,这是一种非常强大的技术,我称之为"填空".

这是一个非常简短的例子:

骨架1:

<html xmlns:gen="my:tranform-generated">
 <body>
  <h1>Hi <gen:fname/>!</h1>
 </body>
</html>
Run Code Online (Sandbox Code Playgroud)

骷髅2:

<html xmlns:gen="my:tranform-generated">
 <body>
  <h1>Hi <gen:fname/> <gen:lname/>!</h1>

  You are <gen:age/> years old.
 </body>
</html>
Run Code Online (Sandbox Code Playgroud)

XSLT转换作为外部参数传递给"要使用的骨架"的Uri,并且它"按原样"复制所有节点,但特殊命名的元素(其名称在特殊命名空间中"my:tranform-"除外)生成的").它们被在XSLT转换中与它们匹配的模板的结果所替代.

以下是此类转换的示例:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:gen="my:tranform-generated" exclude-result-prefixes="gen">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pSkeleton" select="'file:///c:/temp/delete/Skeleton1.xml'"/>

 <xsl:variable name="vData" select="/"/>

 <xsl:template match="/">
  <xsl:apply-templates select="document($pSkeleton)/*"/>
 </xsl:template>

 <xsl:template match="*">
     <xsl:element name="{name()}">
       <xsl:copy-of select="namespace::*[not(. = 'my:tranform-generated')]"/>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:element>
 </xsl:template>

 <xsl:template match="@*">
  <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
 </xsl:template>

 <xsl:template match="*[namespace-uri()='my:tranform-generated']">
  <xsl:value-of select="$vData/*/*[name() = local-name(current())]"/>
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

当此转换应用于此XML文档时:

<person>
 <fname>John</fname>
 <lname>Smith</lname>
 <age>25</age>
</person>
Run Code Online (Sandbox Code Playgroud)

产生了想要的正确结果(使用Skeleton1.xml):

<html>
   <body>
      <h1>Hi John!</h1>
   </body>
</html>
Run Code Online (Sandbox Code Playgroud)

当对同一个XML文档应用相同的转换,但$pSkeleton传递给它的外部参数的值为"file:///c:/temp/delete/Skeleton2.xml",那么我们再次得到想要的结果(格式化的Skeleton2):

<html>
   <body>
      <h1>Hi JohnSmith!</h1>

      You are 25 years old.

   </body>
</html>
Run Code Online (Sandbox Code Playgroud)

更新:

以下是如何处理迭代的示例 - 根据OP的要求:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:gen="my:tranform-generated" exclude-result-prefixes="gen">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pSkeleton" select="'file:///c:/temp/delete/Skeleton3.xml'"/>

 <xsl:variable name="vData" select="/"/>

 <xsl:template match="/">
  <xsl:apply-templates select="document($pSkeleton)/*"/>
 </xsl:template>

 <xsl:template match="*">
     <xsl:element name="{name()}">
       <xsl:copy-of select="namespace::*[not(. = 'my:tranform-generated')]"/>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:element>
 </xsl:template>

 <xsl:template match="@*">
  <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
 </xsl:template>

 <xsl:template match="*[namespace-uri()='my:tranform-generated']">
  <xsl:value-of select="$vData/*/*[name() = local-name(current())]"/>
 </xsl:template>

 <xsl:template match="gen:context" priority="2">
     <xsl:apply-templates>
       <xsl:with-param name="pContext"
         select="$vData/*/*[name()=current()/@select][1]"/>
     </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="gen:iterate" priority="2">
  <xsl:param name="pContext"/>

  <xsl:variable name="vDelim" select="string(@delimiter)"/>

  <xsl:for-each select="$pContext/*[name()= current()/@select]">
   <xsl:if test="not(position()=1)"><xsl:copy-of select="$vDelim"/></xsl:if>
   <xsl:copy-of select="node()"/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

Skeleton3.xml:

<html xmlns:gen="my:tranform-generated">
 <body>
  <h1>Hi <gen:fname/> <gen:lname/>!</h1>

  You are <gen:age/> years old.

  Education:
  <gen:context select="education">
    <gen:iterate select="degree" delimiter=", "/>
  </gen:context>
 </body>
</html>
Run Code Online (Sandbox Code Playgroud)

当上面的转换应用于此XML文档时:

<person>
 <fname>John</fname>
 <lname>Smith</lname>
 <age>25</age>

 <education>
  <degree>MSc. Biology</degree>
  <degree>MBa.</degree>
  <degree>PhD. Computer Science</degree>
 </education>
</person>
Run Code Online (Sandbox Code Playgroud)

产生了想要的正确结果:

<html>
   <body>
      <h1>Hi JohnSmith!</h1>

      You are 25 years old.

        Education:
        MSc. Biology, MBa., PhD. Computer Science
   </body>
</html>
Run Code Online (Sandbox Code Playgroud)