2010-12-31 5 views
9

xslt変換をデイジーチェーンしなければならない状況があります(つまり、あるxslt変換の出力を別のxslt変換に入力する)。最初の変換は、たくさんのxsl:choiceとancestor xpathsでかなり複雑です。私の考えは、xmlをxmlに変換して、htmlに簡単に変換できるようにすることです。xsltをデイジーチェーン接続することは受け入れられていますか?

私の質問は「この標準的な練習ですか、それとも何か不足していますか?

ありがとうございます。

スティーブン

+0

良い質問、+1。解説と完全なコード例を参照してください。 :) –

+1

はい、受け入れられますが、必ずしもそうである必要はありません。 Javaを使用している場合は、Transformerfactoryを連続的な変換を行い、不要な解析操作を避けるように構成できます。 http://stackoverflow.com/questions/1312406/efficient-xslt-pipeline-in-java-or-redirecting-results-to-sources/1319774#1319774 –

答えて

0

私はあなたが別のものに直接1つのXML方言を変換することができるので、それは特に、標準練習だったとは思わないでしょう。

しかし、処理が複雑な場合、それを複数のステップに分割する(各ステップで異なる変換を適用する)ことは、実際に各ステップを単純化して意味をなすことができます。

本当に特定の状況によって異なります。ベンダー固有のxxx:node-set()機能を使用する必要があり、完全にXSLT 1.0でこれをやっても変換のチェーンを実行

9

、XSLTアプリケーションでかなり頻繁に使用されています。 XSLT 2.0では、悪名高いRTFデータ型がそこで排除されるため、このような拡張は必要ありません。

:この変換は、以下のXML文書に印加されたとき

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

<xsl:template match="/"> 
    <xsl:variable name="vrtfPass1"> 
    <xsl:apply-templates select="/*/*"/> 
    </xsl:variable> 

    <xsl:variable name="vPass1" 
     select="ext:node-set($vrtfPass1)"/> 

    <xsl:apply-templates mode="pass2" 
     select="$vPass1/*"/> 
</xsl:template> 

<xsl:template match="num[. mod 2 = 1]"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

<xsl:template match="num" mode="pass2"> 
    <xsl:copy> 
    <xsl:value-of select=". *2"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

:ここ

は、例えば(あまりにも単純な意味のあることが、これがどのように行われるか完全に説明する)であります

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

欲しい、正しい結果が得られる

<num>2</num> 
<num>6</num> 
<num>10</num> 
<num>14</num> 
<num>18</num> 

説明:最初のステップで

  1. は、XML文書が変換され、その結果が変数$vrtfPass1の値として定義されます。これは、奇数値(偶数でない)を持つnum要素のみをコピーします。

  2. $vrtfPass1変数は、型RTFのもので、私たちは(ほとんどのXSLT 1.0プロセッサによって実装される)EXSLT関数ext:node-setを使用して、別の変数を定義する、通常のツリーに変換XPathはを表現するために直接使用できません - - $vPass1の値はこのツリーです。変数$vPass1の値として保持される第1の変換の結果に - 私たちは、今変換の我々の鎖に第2の変換を実行

  3. 。ファーストパステンプレートを使いこなすのではなく、新しい処理を "pass2"という名前のモードにするよう指定します。このモードでは、任意のnumの値に2が掛けられます。

XSLT 2.0ソリューション(なしRTFs):

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

<xsl:template match="/"> 
    <xsl:variable name="vPass1" > 
    <xsl:apply-templates select="/*/*"/> 
    </xsl:variable> 
    <xsl:apply-templates mode="pass2" 
     select="$vPass1/*"/> 
</xsl:template> 

<xsl:template match="num[. mod 2 = 1]"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

<xsl:template match="num" mode="pass2"> 
    <xsl:copy> 
    <xsl:value-of select=". *2"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 
1

これはあなたの状況である(またはあなたの状況になる場合があります)した場合:

  1. はmediary XMLに初期XMLを変換。
  2. おそらくmediary xmlをfinal1_htmlに変換します。
  3. おそらくmediary xmlをfinal2_htmlに変換します(final1_htmlのようにはまったくありません)。

または

  1. mediary XMLに初期XMLを変換。これは時間とともに変化する可能性があります。
  2. mediary xmlをfinal_htmlに変換します。これは時間の経過とともに変化する可能性は低いです。

次に、2段階の変換を使用することは理にかなっています。

これはあなたの状況にある場合:

  1. はmediary XMLに初期XMLを変換。
  2. mediary xmlをfinal_htmlに変換します。

次に、2つのステッピングを考慮しないでください。代わりに、ただ1つの変換を実行してください。

関連する問題