1

次の XSLT コードを実行すると:

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

 <xsl:key name="kValueByVal" match="variable_name/@value"
  use="."/>

 <xsl:template match="assessment">
  <xsl:for-each select="
   /*/*/variable/attributes/variable_name/@value
             [generate-id()
             =
              generate-id(key('kValueByVal', .)[1])
             ]
   ">
     <xsl:value-of select=
     "concat(., ' ', count(key('kValueByVal', .)), '&#xA;')"/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

次の XML で:

<assessment>
    <variables>
        <variable>
            <attributes>
                <variable_name value="FRED"/>
            </attributes>
        </variable>
    </variables>
    <variables>
        <variable>
            <attributes>
                <variable_name value="MORTIMER"/>
            </attributes>
        </variable>
    </variables>
    <variables>
        <variable>
            <attributes>
                <variable_name value="FRED"/>
            </attributes>
        </variable>
    </variables>
</assessment>

目的の出力が得られます。

FRED 2
MORTIMER 1

(必要に応じて、詳細については私の元の質問を参照してください。)

ただし、この入力で実行すると:

<ExamStore>
    <assessment>
        <variables>
            <variable>
                <attributes>
                    <variable_name value="FRED"/>
                </attributes>
            </variable>
        </variables>
        <variables>
            <variable>
                <attributes>
                    <variable_name value="MORTIMER"/>
                </attributes>
            </variable>
        </variables>
        <variables>
            <variable>
                <attributes>
                    <variable_name value="FRED"/>
                </attributes>
            </variable>
        </variables>
    </assessment>
</ExamStore>

私は何も得ません。(元の入力を ExamStore タグでラップしただけであることに注意してください。) 同じ出力が得られることを期待し、望んでいました。

なぜ私はしないのですか?元の XSLT コードを変更して同じ出力を得るにはどうすればよいですか?

4

3 に答える 3

1

XMLドキュメントにさらに別のレベルを導入すると、元のソリューションで使用されていた絶対XPath式が台無しになりました(元のXMLファイルの直後に保持されます)。

したがって、XPath式を新しい状況で機能させるには、次のようにします。

置換

/*/*/variable/attributes/variable_name/@value 

/*/*/*/variable/attributes/variable_name/@value

そして今、あなたは再び望みのきちんとした結果を得る:

FRED 2
MORTIMER 1

変換を適用する可能性のあるXMLドキュメントのセットに関するプロパティ/保証/制約を提供していないため、「独立した」ソリューションを提供することは決してありません。

あなたが使用した元の質問では:

.//variables/variable/attributes/variable_name

オフassessment

これが、ソリューションで絶対XPath式を使用した理由です。別のXMLドキュメントvariable_nameに、祖先のチェーンが存在しないような要素が存在しないという保証はありませんでした。この場合、このような「不規則な」要素variables/variable/attributesの値に関心がなかったことを意味します。variable_name

教訓は、質問を定義する際にあまり具体的であってはならず、一般的な解決策が必要であるということです。:)

于 2010-07-16T02:55:58.000 に答える
1

/*/*/variable/attributes/variable_name/...ノードツリーの上位に別のノードを追加したため、select xpathは正しくありません。

真の独立性が必要な場合は、次のようなものを使用する必要があります。

//variable/attributes/variable_name/...

...(最初の二重スラッシュではありません) しかし、これはその構造のすべての出現をキャッチするため、かなり危険です。

それ以外の場合は、xpath の先頭に別のパスを追加するだけです/*

于 2010-07-15T15:00:02.560 に答える
0

実際の構造の独立性については、次を使用する必要があります。

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

 <xsl:key name="kValueByVal" match="variable_name/@value"
  use="."/>

 <xsl:template match="variable_name[@value
             [generate-id()
             =
              generate-id(key('kValueByVal', .)[1])
             ]]">
     <xsl:value-of select=
     "concat(@value, ' ', count(key('kValueByVal', @value)), '&#xA;')"/>
 </xsl:template>
</xsl:stylesheet>

最初の入力の結果:

FRED 2
MORTIMER 1

2 番目の入力の結果:

FRED 2
MORTIMER 1

://最初の XPath 演算子として使用しないでください。

于 2010-07-15T15:15:26.387 に答える