3

同じXSLTスタイルシートに異なるHTMLレイアウトを使用することは可能ですか?

私はXSLTについて読んでいますが、私が見るほとんどの例は、HTMLコードが実際にスタイルシートに埋め込まれていることを示しています。

同じスタイルシートを複数のHTMLレイアウトに使用することは可能ですか?(私はVelocityがどのように機能するかと同じように考えています-つまり、同じVelocityタグを使用して複数のHTMLファイルを処理できます)。

XSLTを処理するためにJavaXalanプロセッサを使用しています。

編集

以下の@DimitreNovatchevアプローチを試しましたが、完全に機能します。唯一のことは、要素のループをどのように処理するかです。たとえば、xmlドキュメントが次のように変更された場合:

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

各年齢要素をどのように繰り返すことができますか?

これが私が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>

期待される出力

上記の出力を

Hi JohnSmith!
You are 25 years old. 

25, 33, 55
4

2 に答える 2

6

はい、これは非常に強力な手法であり、私は「空白を埋める」と呼んでいます。

これは非常に短い例です:

スケルトン1:

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

スケルトン2:

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

  You are <gen:age/> years old.
 </body>
</html>

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>

この変換がこのXMLドキュメントに適用される場合

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

(Skeleton1.xmlを使用して)必要な正しい結果が生成されます。

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

同じ変換が同じXMLドキュメントに適用されている$pSkeletonが、それに渡された外部パラメーターの値がである"file:///c:/temp/delete/Skeleton2.xml"場合、再び必要な結果(フォーマットされたSkeleton2)が得られます。

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

      You are 25 years old.

   </body>
</html>

更新

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>

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>

上記の変換がこの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>

必要な正しい結果が生成されます:

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

      You are 25 years old.

        Education:
        MSc. Biology, MBa., PhD. Computer Science
   </body>
</html>
于 2012-11-14T13:25:31.250 に答える
0

はい、これは可能です。xsl:ifタグでhtmlのブロックを囲むことができます

例えば:

<xsl:if test="value &gt; 75000"><p>Print out this html</p></xsl:if>
于 2012-11-14T11:34:42.863 に答える