2012-04-14 10 views
2

ルート要素がデフォルトのネームスペース属性を持っていないときにxsltの動作に特有の違いが発生しました。
この違いがなぜ発生するのでしょうか。xsl:テンプレートの一致属性:デフォルトネームスペースに関連する方法

XML入力が

<root> 
    <content>xxx</content> 
</root> 

次の変換が適用される場合

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
     <root> 
      <xsl:apply-templates/> 
     </root> 
    </xsl:template> 

    <xsl:template match="content"> 
     <w>x</w> 
    </xsl:template> 

</xsl:stylesheet> 

結果が期待

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <w>x</w> 
</root> 

であるが、同じ変換が

に適用した場合であります
<root xmlns="http://test.com"> 
    <content>xxx</content> 
</root> 

結果が異なっており、単にデフォルトのテンプレート(効果的に出力テキストノード値「XXX」)の申請に基づき、次のとおりです。

<?xml version="1.0" encoding="UTF-8"?> 
<root>xxx</root> 

追加

これは正常な動作である場合にはこの場合、2番目のケースのcontent要素に一致させるためには、どの一致属性値が必要ですか?

答えて

2

あなたの質問は何ですか?あなたが単に説明を探しているなら、以下は簡単なものです。あなたが観察しているのは、仕様に応じた適切な動作です。あなたが何かの上に名前空間を置くと、パーサは基本的にそれを全く別の要素として扱います(名前は同じですが名前空間はありません)。したがって、第2の状況では、<xsl:template match="content">と言うとき、http://test.comという名前空間(その親の名前空間宣言を介して)の下にあるので、XMLファイルの<content>要素と一致しません。したがって、既定のテンプレートが引き継ぎます。

+1

少し予期していませんが、もう一度疑問があります:2番目のケースではどのように 'content'要素に一致しますか? – Maestro13

+1

fyi要素を名前空間に一致させるには、いくつかの方法があります。 1つの方法は、あなたのXSL宣言にそれを加えることです。つまり、 '"です。この場合、テンプレートの一致ステートメントを ''に変更する必要があります。テンプレートマッチステートメントを '' – user1263226

+0

に変更するだけでよいのですが、最後の文章ではアポストロフィ、すなわち 'content' – user1263226

5

これはXPath/XSLTで最もよくある質問です。

接頭辞のない要素名は、XPathによって「名前空間なし」に属するものとして扱われます。

W3C Xpath specificationを言う:

QNameが接頭辞を持っていない場合、名前空間URIがnullです。

したがって、既定の名前空間を持つドキュメントでは、XMLドキュメントに「名前空間なし」の要素がないため、名前が固定されていない要素(「someName」など)の参照は何も選択されません。 someNameは、「名前空間なし」に属する名前「someName」を持つ要素を意味します。

ソリューションは:私たちは名前で要素を選択したい場合は

、私たちは、その名前の前に付ける必要がありますし、プレフィックスはデフォルトの名前空間に関連付けられている必要があります。

この変換

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:x="http://test.com" exclude-result-prefixes="x"> 
     <xsl:output omit-xml-declaration="yes" indent="yes"/> 
     <xsl:strip-space elements="*"/> 

     <xsl:template match="/"> 
      <root> 
       <xsl:apply-templates/> 
      </root> 
     </xsl:template> 

     <xsl:template match="x:content"> 
      <w>x</w> 
     </xsl:template> 
</xsl:stylesheet> 

は、デフォルトの名前空間を提供するXML文書に適用される:

<root> 
    <w>x</w> 
</root> 

<root xmlns="http://test.com"> 
    <content>xxx</content> 
</root> 

は指名手配、正しい結果を生成

+0

はい、デフォルトの名前空間が変更されることを知っていたはずです。デフォルトでないものだけが要素名に接頭辞を付けること(または 'local-name()'を使用する必要がある)。 – Maestro13

+0

@ Maestro13:これは覚えておくべきルールです。デフォルトの名前空間が使用されている場合、名前がXML文書内に固定されていない特定の要素を選択するには、XPath式に接頭辞を付ける必要があります。私は自分の答えを編集しました。そして、完全な変換に加えて、私はW3C XPath仕様の正確な見積もりとそのテキストを含むセクションへのリンクを提供します。 –

+0

これは1ヶ月前に来るものです:[namespace-stopping-xslt-working](http://stackoverflow.com/questions/9886520/namespace-stopping-xslt-working) - ついにそれは私にとって意味があります今すぐ! – Maestro13

関連する問題