5

次のようなxmlファイルがあります。

<root>
    <item>
        <name>one</name>
        <status>good</status>
    </item>
    <item>
        <name>two</name>
        <status>good</status>
    </item>
    <item>
        <name>three</name>
        <status>bad</status>
    </item>
    <item>
        <name>four</name>
        <status>ugly</status>
    </item>
    <item>
        <name>five</name>
        <status>bad</status>
    </item>
</root>

XSLT を使用してこれを変換し、次のようなものを取得します。

<root>
    <items><status>good</status>
        <name>one</name>
        <name>two</name>
    </items>
    <items><status>bad</status>
        <name>three</name>
        <name>five</name>
    </items>
    <items><status>ugly</status>
        <name>four</name>
    </items>
</root>

言い換えれば、それぞれにステータスを持つアイテムのリストを取得し、それをそれぞれにアイテムのリストを持つステータスのリストに変換したいと考えています。

私が最初に考えたのは、各ステータス タイプに順番に一致するテンプレートの適用を行うことでしたが、それは、ステータスの完全なリストを知る必要があることを意味します。それを行うより良い方法はありますか?

助けてくれてありがとう。

4

4 に答える 4

8

ムンクが助けに!

<?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" encoding="UTF-8"/>

    <xsl:key name="muench" match="/root/item/status" use="."/>

    <xsl:template match="/">
        <root>
        <xsl:for-each select="/root/item/status[generate-id() = generate-id(key('muench',.)[1])]">
            <xsl:call-template name="pivot">
                <xsl:with-param name="status" select="."/>
            </xsl:call-template>
        </xsl:for-each>
        </root>
    </xsl:template>

    <xsl:template name="pivot">
        <xsl:param name="status"/>
        <items>
            <status><xsl:value-of select="$status"/></status>
            <xsl:for-each select="/root/item[status=$status]">
                <name><xsl:value-of select="name"/></name>
            </xsl:for-each>
        </items>
    </xsl:template>

</xsl:stylesheet>
于 2009-01-08T14:37:33.787 に答える
4

はい、これは XSLT 1.0 で実行できます

<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="kStatByVal" 
         match="status" use="."/>
    <!--                                   -->
    <xsl:key name="kItemByStat" 
         match="item" use="status"/>
    <!--                                   -->
    <xsl:variable name="vDoc" select="/"/>

    <xsl:template match="/">
      <top>
        <xsl:for-each select=
        "/*/*/status[generate-id()
                    =
                     generate-id(key('kStatByVal',.)[1])
                    ]">
          <items>
            <status><xsl:value-of select="."/></status>
          <xsl:for-each select="key('kItemByStat', .)">
            <xsl:copy-of select="name"/>
          </xsl:for-each>
          </items>
        </xsl:for-each>
      </top>
    </xsl:template>
</xsl:stylesheet>

この変換が元の XML ドキュメントに適用されると、次のようになります。

<root>
    <item>
        <name>one</name>
        <status>good</status>
    </item>
    <item>
        <name>two</name>
        <status>good</status>
    </item>
    <item>
        <name>three</name>
        <status>bad</status>
    </item>
    <item>
        <name>four</name>
        <status>ugly</status>
    </item>
    <item>
        <name>five</name>
        <status>bad</status>
    </item>
</root>

必要な結果が生成されます。

<top>
    <items>
        <status>good</status>
        <name>one</name>
        <name>two</name>
    </items>
    <items>
        <status>bad</status>
        <name>three</name>
        <name>five</name>
    </items>
    <items>
        <status>ugly</status>
        <name>four</name>
    </items>
</top>

の使用に注意してください:

  1. グループ化のためのMuenchian メソッド

  2. 使い方<xsl:key>key()機能

于 2009-01-08T14:52:22.167 に答える
0

xslt エンジンによって異なります。拡張子なしで xslt 1.0 を使用している場合、そのアプローチは確かに最適です。

一方、exslt (特にノードセット拡張) または xslt 2.0 の使用が許可されている場合は、より一般的な方法で実行できます。

  1. 入手可能なステータスをすべて集める
  2. 得られた結果からノードセットを作成する
  3. このノード セットを反復処理し、反復処理の現在の要素に基づいてステータス ベースをフィルター処理して、ピボットを作成します。

ただし、それを行う前に、数セットのステータスしかない場合は過剰になる可能性があり、別のステータスを追加することは非常にまれであることを考慮してください.

于 2009-01-08T14:20:44.913 に答える
0

XSLT 2.0 では、ミューエンチャンのグループ化を標準のグループ化メカニズムに置き換えることができます。指定された回答に適用すると、xslt は次のようになります。

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

    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

    <xsl:key name="muench" match="/root/item/status" use="."/>

    <xsl:template match="/">
        <root>
        <xsl:for-each-group select="/root/item/status" group-by="key('muench', .)">
            <xsl:call-template name="pivot">
                <xsl:with-param name="status" select="."/>
            </xsl:call-template>
        </xsl:for-each-group>
        </root>
    </xsl:template>

    <xsl:template name="pivot">
        <xsl:param name="status"/>
        <items>
            <status><xsl:value-of select="$status"/></status>
            <xsl:for-each select="/root/item[status=$status]">
                <name><xsl:value-of select="name"/></name>
            </xsl:for-each>
        </items>
    </xsl:template>

</xsl:stylesheet>
于 2013-10-18T10:04:16.570 に答える