0

次の XML があります。

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

その XML を処理するための次の XSLT があります。

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

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

 <xsl:template match="assessment">
     <xsl:for-each select="
      .//item//variables//variable_name/@value
      ">
        <xsl:value-of select=
        "concat(., ' ', count(key('kValueByVal', .)), '&#xA;')"/>
         <br/>
     </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

それは次のように出力します。これはほとんど私が望むものです:

MORTIMER 2
FRED 1
MORTIMER 2

それぞれの variable_names と、それぞれの発生回数がリストされます。唯一の問題は、変数名が 1 回だけではなく発生するたびに、このカウントが 1 回与えられることです。

これは私が出力したいものです:

MORTIMER 2
FRED 1

XSLTコードを変更してそれを得るにはどうすればよいですか? XSLT 1.0 を使用していることに注意してください。

うまくいくように見える次のソリューションは、何も出力しません。

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

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

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

5 に答える 5

2

Muenchian グループ化がどのように機能するかを本当に理解する必要があります。そうしないと、同じ質問のバリエーションを永遠に尋ねることになります。

Jeni Tennison のチュートリアルを読んでください。

最新の質問に対する解決策は次のとおりです。

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

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

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

提供された XML ドキュメントに対してこの変換が実行されると、必要な結果が生成されます。

MORTIMER 2
FRED 1
于 2010-07-16T18:35:22.427 に答える
1

XSLT 2.0 を使用しているので、組み込みのグループ化機能を使用します。(以前のバージョンでは、おそらく Muenchian のグループ化を調べた方がよいでしょう。)

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

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

 <xsl:template match="assessment">
     <xsl:for-each-group select=".//item//variables//variable_name" group-by="@value">
                <xsl:value-of select="concat(current-grouping-key(), ' ', count(current-group()), '&#xA;')"/>
        <br/>
     </xsl:for-each-group>
 </xsl:template>
</xsl:stylesheet>
于 2010-07-16T15:49:01.340 に答える
1

これは XSLT 1.0 で行われます。

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

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

 <xsl:template match="assessment">
     <xsl:for-each select="
      //item//variables//variable_name[not(@value=ancestor::item/preceding-sibling::item//variables//variable_name/@value)]
      ">
        <xsl:value-of select=
        "concat(@value, ' ', count(key('kValueByVal', @value)), '&#xA;')"/>
         <br/>
     </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

私が得る出力は

MORTIMER 2
<br />FRED 1
<br />

ドキュメント構造 (祖先::item ビット) についてもう少し想定していることに注意してください。ただし、そこから取得できるはずです。

于 2010-07-16T16:47:04.207 に答える
1

あなたはあなたが求めているものを手に入れます:

<xsl:for-each select=".//item//variables//variable_name/@value"> 

つまり、これらの属性のそれぞれについて

グループ化するときは、次のように言う必要があります。

そして、どれが他に類を見ないものであるかをどうやって知るのですか?Muenchian メソッドを使用する場合:

<xsl:for-each select=".//item//variables//variable_name/@value[generate-id()
                                                               =
                                                               generate-id(key('kValueByVal',.)[1])]">

つまり、その鍵を最初に持った人たちです。

EDIT// :また、入力スキーマがわかっている場合は避けてください。

EDIT : キーを変更したことがわかります... それで、あなたにとって新しいキーは誰ですか? はい!variable_nameエレメント:

<xsl:for-each select=".//item//variables//variable_name[generate-id()
                                                        =
                                                        generate-id(key('kValueByVal',@value)[1])]">
于 2010-07-16T16:13:24.800 に答える
0
<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

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

 <xsl:template match="assessment">
     <xsl:for-each 
              select="//item//variables//variable_name[
                          generate-id() = 
                              generate-id(key('kValueByVal', @value)[1])]">
        <xsl:value-of select=
        "concat(./@value, ' ', count(key('kValueByVal', ./@value)), '&#xA;')"/>
         <br/>
     </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>
于 2010-07-16T16:40:59.510 に答える