2013-04-07 18 views
8

this questionの答えで間違いを見て、それを指摘したと思いました。私は間違っていると言われ、私の答えは後で削除されました。XSLで一致する子要素

私はまだ間違っていた方法を見ていません。したがって、私はここに投稿していると誰かが私の誤解を説明することを望む。

私が答えた答えは、apply-templatesの使用方法を説明したものです。これは、テンプレートがマッチするだろうか説明し、次のXMLとXSLを含んでいた:

<!-- sample XML snippet --> 
<xml> 
    <foo /><bar /><baz /> 
</xml> 

<!-- sample XSLT snippet --> 
<xsl:template match="xml"> 
    <xsl:apply-templates select="*" /> <!-- three nodes selected here --> 
</xsl:template> 

<xsl:template match="foo"> <!-- will be called once --> 
    <xsl:text>foo element encountered</xsl:text> 
</xsl:template> 

<xsl:template match="xml/*"> <!-- will be called twice --> 
    <xsl:text>other element countered</xsl:text> 
</xsl:template> 

私のコメントがあるべきで、最後のテンプレートました:現在のノードがすでに<xml>

あるので

<xsl:template match="*"> <!-- will be called twice --> 
    <xsl:text>other element countered</xsl:text> 
</xsl:template> 

私は言われました:

いいえ、xml/*は、次の子要素に一致するパターンです。要素名は xmlです。

このXMLで、

しかし、元の答えをテスト:

<xml> 
    <foo /><bar /><baz /> 
</xml> 

そして、このXSLスタイルシート(上記のスニペットを記入):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 

<xsl:template match="xml"> 
    <xsl:apply-templates select="*" /> <!-- three nodes selected here --> 
</xsl:template> 

<xsl:template match="foo"> <!-- will be called once --> 
    <xsl:text>foo element encountered.&#xa;</xsl:text> 
</xsl:template> 

<xsl:template match="xml/*"> <!-- will be called twice --> 
    <xsl:text>other element countered.&#xa;</xsl:text> 
</xsl:template> 

</xsl:stylesheet> 

私が手:

私が手に私の答えどおり

<xsl:template match="*"> <!-- will be called twice --> 
    <xsl:text>other element countered.&#xa;</xsl:text> 
</xsl:template> 

に見える
foo element encountered. 
other element countered. 
other element countered. 

私はとの最後のテンプレートを置き換える場合は、私の '修正' バージョン

のテスト

other element countered. 
other element countered. 
other element countered. 

正しい。

私の質問がガイドラインに違反しないことを願っていますが、間違っているとは思えません。

PS。私はまだコメントを投稿するのに十分なポイントがないので、他の質問に対する私の元の応答が答えとして投稿されたことになります。私は何が最善のことであるか分からなかった...

+1

私の愚かな間違いを見つけてくれてありがとう、もう1つのスレッドで修正されました。これは何年もの間答えを見た他の誰もが気づかなかった。 – Tomalak

答えて

6

これは、rules on the default priority of templatesに従って正しいです。 fooに一致するテンプレートにはデフォルトの優先度0があり、*にはデフォルトの優先度-0.5が1つありますが、一致するものはデフォルト優先度0.5になります。xml/*xml/*テンプレートはfooよりも具体的であると考えられますので、どちらかが一致すると勝ちます。

ですから、テンプレートの一致式が*いうよりxml/*なるために必要なことを正しかった、ではなく、右の理由のために - 現在のノードがxmlあり、そしてそれが適用されるときapply-templates select="*"ためxml/*テンプレート一致優先度の高いpriorityが0.5以上の別のテンプレートがある場合を除き、選択された要素のいずれか(すべてがxmlの子であるため)。

4

私はあなたが他のスレッドで間違っていると言った人でした。問題をより詳細に見てから、私はあなたがTomalakが間違いを犯したと指摘しても間違いないと指摘しました。 (あなたのコメントを正しく理解していれば)。 match="xml/*"が呼び出されたときに現在のコンテキストが<xml>ノードであったかどうかにかかわらず、<xml>要素の子ノードと一致するのはですか? match=""の式では、「現在のノード」はテンプレートが適用されているノードであり、apply-templatesが呼び出されたコンテキストではないため、このテンプレートでは現在のノードはfoo,barbazとなります。上記の実験結果から、xml/*xmlの子要素の一致に成功しますが、実際にはと一致していることがTomalakより明らかになりますとなります。

match="xml/*"の問題は、があまりにも具体的でであり、Tomalakが意図したとは逆の効果があることです。彼はこれが他の方法と一致しなかったxmlの子供のためのキャッチオールだと思っていたが、Ian Robertsが説明するように、このテンプレートはfooテンプレートよりも高い数字ので始まり、 xmlノード。

私は自分自身のコメントを書くことができなくなっていますが、すぐにあなたのことができます。そして、あなた自身の新しい質問を作成して、別のスレッドに関する質問をすることも可能です。他の回答にコメントするための回答を作成しないでください。

+0

+1これは恥ずかしいです。 :) – Tomalak

関連する問題