xslt変換をデイジーチェーンしなければならない状況があります(つまり、あるxslt変換の出力を別のxslt変換に入力する)。最初の変換は、たくさんのxsl:choiceとancestor xpathsでかなり複雑です。私の考えは、xmlをxmlに変換して、htmlに簡単に変換できるようにすることです。xsltをデイジーチェーン接続することは受け入れられていますか?
私の質問は「この標準的な練習ですか、それとも何か不足していますか?
ありがとうございます。
スティーブン
xslt変換をデイジーチェーンしなければならない状況があります(つまり、あるxslt変換の出力を別のxslt変換に入力する)。最初の変換は、たくさんのxsl:choiceとancestor xpathsでかなり複雑です。私の考えは、xmlをxmlに変換して、htmlに簡単に変換できるようにすることです。xsltをデイジーチェーン接続することは受け入れられていますか?
私の質問は「この標準的な練習ですか、それとも何か不足していますか?
ありがとうございます。
スティーブン
私はあなたが別のものに直接1つのXML方言を変換することができるので、それは特に、標準練習だったとは思わないでしょう。
しかし、処理が複雑な場合、それを複数のステップに分割する(各ステップで異なる変換を適用する)ことは、実際に各ステップを単純化して意味をなすことができます。
本当に特定の状況によって異なります。ベンダー固有のxxx:node-set()
機能を使用する必要があり、完全にXSLT 1.0でこれをやっても変換のチェーンを実行
、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>
説明:最初のステップで
は、XML文書が変換され、その結果が変数$vrtfPass1
の値として定義されます。これは、奇数値(偶数でない)を持つnum
要素のみをコピーします。
$vrtfPass1
変数は、型RTFのもので、私たちは(ほとんどのXSLT 1.0プロセッサによって実装される)EXSLT関数ext:node-set
を使用して、別の変数を定義する、通常のツリーに変換XPathはを表現するために直接使用できません - - $vPass1
の値はこのツリーです。変数$vPass1
の値として保持される第1の変換の結果に - 私たちは、今変換の我々の鎖に第2の変換を実行
。ファーストパステンプレートを使いこなすのではなく、新しい処理を "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>
これはあなたの状況である(またはあなたの状況になる場合があります)した場合:
または
次に、2段階の変換を使用することは理にかなっています。
これはあなたの状況にある場合:
次に、2つのステッピングを考慮しないでください。代わりに、ただ1つの変換を実行してください。
良い質問、+1。解説と完全なコード例を参照してください。 :) –
はい、受け入れられますが、必ずしもそうである必要はありません。 Javaを使用している場合は、Transformerfactoryを連続的な変換を行い、不要な解析操作を避けるように構成できます。 http://stackoverflow.com/questions/1312406/efficient-xslt-pipeline-in-java-or-redirecting-results-to-sources/1319774#1319774 –