3

ルート要素にデフォルトの名前空間属性がある場合とない場合では、xslt の動作に独特の違いがありました。
なぜこのような違いが生じるのか不思議です。

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>

添加

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

4

2 に答える 2

5

XPath/XSLT で最も多い FAQです。

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

W3C Xpath 仕様にのように書かれています。

QName にプレフィックスがない場合、名前空間 URI は null です。

したがって、デフォルトの名前空間を持つドキュメントでは、接頭辞のない名前 (「someName」など) を持つ要素への参照は、XML ドキュメントの「名前空間なし」には要素がないため、何も選択しませんが、名前が「」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 xmlns="http://test.com">
    <content>xxx</content>
</root>

必要な正しい結果が生成されます

<root>
   <w>x</w>
</root>
于 2012-04-14T21:21:02.200 に答える
2

それで、あなたの質問は正確には何ですか?単に説明が必要な場合は、以下に簡単な説明を示します。あなたが観察しているのは、仕様に従った適切な動作です。名前空間を何かに配置すると、パーサーは本質的にそれを完全に別の要素として扱います (名前が同じで名前空間がない要素とは異なります)。したがって、2 番目の状況では、XML ファイル内<xsl:template match="content">の要素と一致しません。これは、(親の名前空間宣言によって) 名前空間に分類されるためです。したがって、デフォルトのテンプレートが引き継ぎます。<content>http://test.com

于 2012-04-14T21:04:42.433 に答える