私は、granchild.xsl で処理された後の結果を child.xsl に転送する必要がある文書 grandchild.xml を持っています。
参照された XSL スタイルシートを使用して処理されることを期待して、結果ドキュメントに要素を追加しようとしxml-stylesheet
ましたが、何も起こりませんでした。
このタスクを達成するための正しい宣言は何ですか? 私はインターネットでたくさん検索しましたが、結果はありません。
ブラウザ内でのマルチパス変換の例を次に示します。
このソース XML ドキュメントがあるとします。
<?xml-stylesheet title="XSL_formatting"
type="text/xsl" href="MultiPassBrowser.xsl"?>
<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>
次の 2 つの XSLT 変換を考えてみましょう。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="num/text()">
<xsl:value-of select=". *2"/>
</xsl:template>
</xsl:stylesheet>
と
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" mode="pass2">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="pass2"/>
</xsl:copy>
</xsl:template>
<xsl:template match="num" mode="pass2">
<p><xsl:value-of select=". +1"/></p>
</xsl:template>
</xsl:stylesheet>
最初の変換では、XML ドキュメントが「そのまま」コピーされますが、すべてのnum
要素の文字列値が 2 倍されます。
2 番目の変換では、XML ドキュメントが「そのまま」コピーされますが、すべてのnum
要素の文字列値がインクリメントされます。
最初の変換の結果に 2 番目の変換が適用される場合、最初のnum
要素から得られる最終的な値は 3、5、7、...、21 でなければなりません。
これら 2 つを結び付ける変換を次に示します。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="ext msxsl">
<xsl:import href="file:///C:/Temp/delete/MultiPassBrowser1.xsl"/>
<xsl:import href="file:///C:/Temp/delete/MultiPassBrowser2.xsl"/>
<xsl:output method="html"/>
<xsl:strip-space elements="*"/>
<msxsl:script language="JScript" implements-prefix="ext">
this['node-set'] = function (x) {
return x;
}
</msxsl:script>
<xsl:template match="/">
<html>
<xsl:variable name="vrtfPass1">
<xsl:apply-templates select="/*"/>
</xsl:variable>
<xsl:apply-templates select="ext:node-set($vrtfPass1)/*/*"
mode="pass2"/>
</html>
</xsl:template>
</xsl:stylesheet>
XML ファイルを IE、Firefox、Safari、および Opera の両方で開いた場合の結果は、正しく、期待されるものです。
<html>
<p>3</p>
<p>5</p>
<p>7</p>
<p>9</p>
<p>11</p>
<p>13</p>
<p>15</p>
<p>17</p>
<p>19</p>
<p>21</p>
</html>
説明:
プライマリ スタイルシート モジュール (XML ドキュメント PI で参照されるもの) は、個別の変換を含む 2 つのスタイルシート モジュールをインポートします。
最初の変換の結果は variavle に取り込まれ$vrtfPass1
ます。
XSLT 1.0 では、このような変数は悪名高い "RTF" (結果ツリー フラグメント) 型であり、直接操作することはできません ( string()
RTF で使用できるのはコピーと関数のみです)。ここではxxx:node-set()
、IE と他の 4 つの主要なブラウザーの両方で機能する、拡張機能の移植可能なバリアントを使用します。この移植可能な拡張機能は、@DavidCarlisle によって最初に提案されたもので、オリジナルは彼のブログにあります。
モード「pass2」のテンプレートは、上記の手順で RTF 変数を変換したノードセットに適用されます。2 番目にインポートされたスタイルシート モジュールのすべてのテンプレートはモード「pass2」であるため、実行用に選択されます。
最終結果が生成されます。
誰かがよくわかっていない限り、ブラウザーで XSLT 出力を再帰的に処理する機能は不可能だと思います。
それを証明するために、IE8、FF14、およびChromeで次のことを試しました...
level1.xml
<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet title="XSL_formatting" type="text/xsl" href="level1.xsl"?>
<data>
<id>Level 1 data</id>
</data>
level1.xsl
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<?xml-stylesheet title="XSL_formatting" type="text/xsl" href="level2.xsl"?>
<data2>
<id2>Level 2: <xsl:value-of select="/data/id"/></id2>
</data2>
</xsl:template>
</xsl:stylesheet>
level2.xsl
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<b>Level 3:</b> <xsl:value-of select="/data2/id2"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
3 つのブラウザーすべてからの結果は、単純に を表示するだけLevel 2: Level 1 Data
です。