1

わかりましたので、この質問XSLT 1.0 sort elementsに基づいて、以下が機能しない理由を理解できません:

次の XML があります。

<?xml version="1.0" encoding="UTF-8"?>
<viewentries>
    <viewentry>
        <entrydata name="Waste">
            <text>Bric-a-Brac</text>
        </entrydata>
        <entrydata name="Disposal">
            <text/>
        </entrydata>
    </viewentry>
    <viewentry>
        <entrydata name="Waste">
            <textlist>
                <text>Paper</text>
                <text>Glass</text>
            </textlist>
        </entrydata>
        <entrydata name="Disposal">
            <text/>
        </entrydata>
    </viewentry>
        <viewentry>
        <entrydata name="Waste">
            <textlist>
                <text>Paper</text>
                <text>Cans</text>
            </textlist>
        </entrydata>
        <entrydata name="Disposal">
                <text>Washing Machines</text>
                <text>Cars</text>
        </entrydata>
    </viewentry>
</viewentries>

そして、次の XSLT:

<?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:key name="k1" match="entrydata[@name = 'Waste' or @name = 'Disposal']//text" use="concat(ancestor::entrydata/@name, '|', .)"/>

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

    <xsl:template match="viewentry">
        <xsl:apply-templates select="entrydata[@name =  'Waste' or @name = 'Disposal']//text
      [generate-id() = generate-id(key('k1', concat(ancestor::entrydata/@name, '|', .))[1])]">
            <xsl:sort select="."/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="text[normalize-space() != '']">
        <category type="{ancestor::entrydata/@name}">
            <xsl:apply-templates/>
        </category>
    </xsl:template>

</xsl:stylesheet>

これにより、次の出力が得られます。

<?xml version="1.0" encoding="UTF-8"?>
<categories>
    <category type="Waste">Bric-a-Brac</category>
    <category type="Waste">Glass</category>
    <category type="Waste">Paper</category>
    <category type="Waste">Cans</category>
    <category type="Disposal">Cars</category>
    <category type="Disposal">Washing Machines</category>
</categories>

ソートされた順序で出力が必要です:

<?xml version="1.0" encoding="UTF-8"?>
<categories>
    <category type="Waste">Bric-a-Brac</category>
    <category type="Waste">Cans</category>
    <category type="Disposal">Cars</category>
    <category type="Waste">Glass</category>
    <category type="Waste">Paper</category>
    <category type="Disposal">Washing Machines</category>
</categories>

私は何を間違っていますか?

編集:

すべての値ではなく、最初の<text>値のみに基づいてソートしているようです。<entrydata><text>

ただし、このスタイルシートは正常に機能します。

<?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:key name="k1" match="entrydata[@name = 'Waste' or @name = 'Disposal']//text" use="concat(ancestor::entrydata/@name, '|', .)"/>

    <xsl:template match="viewentries">
        <categories>
            <xsl:apply-templates select="viewentry/entrydata[@name =  'Waste' or @name = 'Disposal']//text
            [generate-id() = generate-id(key('k1', concat(ancestor::entrydata/@name, '|', .))[1])]">
                <xsl:sort select="."/>          
            </xsl:apply-templates>
        </categories>
    </xsl:template>

    <xsl:template match="text[normalize-space() != '']">
        <category type="{ancestor::entrydata/@name}">
            <xsl:value-of select="."/>
        </category>
    </xsl:template>

</xsl:stylesheet>

最初の例が機能しないのに、2 番目の例が機能する理由を誰かが説明できますか。

4

1 に答える 1

2

最初のテンプレートに並べ替えを適用する理由を誰かが説明できますが、私の元の質問のように2番目のテンプレートに適用すると、機能しません????

これが「2番目のテンプレート」です。

<xsl:template match="text[normalize-space() != '']">
    <category type="{ancestor::entrydata/@name}">
        <xsl:apply-templates>
                <xsl:sort select="."/>            
        </xsl:apply-templates>
    </category>
</xsl:template>

ここでは、現在のノードの子を文字列値で並べ替えます。

ただし、提供されているXMLドキュメントでは、どのtext要素にも単一のテキストノードの子があります。したがって、並べ替えるものはありません。

これと前の質問では、同じエラーをコミットします-並べ替える必要のある要素の子を並べ替えようとしています-あなたはあまりにも遅く並べ替えています。

覚えておいてください

   <xsl:apply-templates/>

の略語です

   <xsl:apply-templates select="child::node()"/>

つまり、これは、「テンプレートを自分に適用する」ではなく、「テンプレートを自分の子供に適用する」ことを意味します。

更新:問題の正しい解決策は次のとおりです。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kCatVal" match="text[text()]" use="concat(../@name, '+', .)"/>

 <xsl:template match="/">
  <categories>
   <xsl:apply-templates select=
    "//text[generate-id()
               =
                generate-id(key('kCatVal',
                                 concat(../@name, '+', .)
                                 )[1]
                            )
                ]">
          <xsl:sort/>
    </xsl:apply-templates>
  </categories>
 </xsl:template>

 <xsl:template match="text">
        <category type="{../@name}"><xsl:value-of select="."/></category>
  </xsl:template>
</xsl:stylesheet>

提供されたXMLドキュメントに適用した場合

<viewentries>
    <viewentry>
        <entrydata name="Waste">
            <text>Bric-a-Brac</text>
        </entrydata>
        <entrydata name="Disposal">
            <text/>
        </entrydata>
    </viewentry>
    <viewentry>
        <entrydata name="Waste">
            <textlist>
                <text>Paper</text>
                <text>Glass</text>
            </textlist>
        </entrydata>
        <entrydata name="Disposal">
            <text/>
        </entrydata>
    </viewentry>
    <viewentry>
        <entrydata name="Waste">
            <textlist>
                <text>Paper</text>
                <text>Cans</text>
            </textlist>
        </entrydata>
        <entrydata name="Disposal">
            <text>Washing Machines</text>
            <text>Cars</text>
        </entrydata>
    </viewentry>
</viewentries>

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

<categories>
   <category type="Waste">Bric-a-Brac</category>
   <category type="">Cans</category>
   <category type="Disposal">Cars</category>
   <category type="">Glass</category>
   <category type="">Paper</category>
   <category type="Disposal">Washing Machines</category>
</categories>

説明

この種のグループ化には、2つの部分からなる複合キーに基づく索引付けが必要です。したがって、のuse属性はxsl:key、これら2つの部分の連結として指定され、どの値にも存在できないことがわかっている文字で結合されます(最初のキーコンポーネントの値が値のプレフィックスである場合の誤検知を回避するため) 2番目の主要コンポーネントの)。

于 2012-07-18T01:22:19.323 に答える