0

私は XSLT に少し慣れていないので、基本的な質問で申し訳ありません。

<cell> XML (以下) から 3 番目 ( CODE1、CODE2) の値を各ノードから取り出してドロップダウン ボックスに配置する XSL スタイルシートを作成しようとしています。また、各ノードを比較して、反復的なものをすべて取り除き、CODE1、CODE1、CODE2 ではなく、CODE1 と CODE2 の 1 つのインスタンスのみを表示するようにします。

XML:

<dvm>
  <description>This is a description</description>
  <columns>
    <column name="lang"/>
    <column name="text"/>
    <column name="code" qualifier="true" order="1"/>
    <column name="comm" qualifier="true" order="2"/>
    <column name="subj"/>
    <column name="copy"/>
    <column name="flag"/>
 </columns>
 <rows>
   <row>
     <cell>English</cell>
     <cell></cell>
     <cell>CODE1</cell>
     <cell>Fixed</cell>
     <cell>Title1</cell>
     <cell/><cell/>
     <cell/><cell/>
  </row>
  <row>
     <cell>English</cell>
     <cell></cell>
     <cell>CODE1</cell>
     <cell>Wired</cell>
     <cell>Title2</cell>
     <cell/><cell/>
     <cell/><cell/>
  </row>
  <row>
     <cell>English</cell>
     <cell></cell>
     <cell>CODE2</cell>
     <cell>Fixed</cell>
     <cell>Title3</cell>
     <cell/><cell/>
     <cell/><cell/>
  </row>
</dvm>
4

2 に答える 2

2

重複の削除は、一般に「グループ化」と呼ばれる問題のクラスの特殊なケースです。XSLT 2.0 には、グループ化の問題を解決するための機能がいくつかあります。distinct-values() 関数と xsl:for-each-group 命令です。XSLT 1.0 では、それはより困難です: 「Muenchian grouping」を検索してください (または、ここで説明するよりも時間があれば誰かを待ってください...)

于 2012-04-17T15:17:22.457 に答える
0

XSLT 2.0 を適用できる場合は、次を使用します。

<xsl:value-of select="distinct-values(dvm/rows/row/cell[3])"/>

XSLT 1.0 では、Michael Kay が述べた Muenchian グループ化を使用します。デモンストレーション:

<?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" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:key name="Cells" match="dvm/rows/row/cell[3]" use="."/>
    <xsl:template match="/">
        <root>
            <w>
                <xsl:for-each select="dvm/rows/row/cell[3]">
                    <item>
                        <xsl:value-of select="."/>
                    </item>
                </xsl:for-each>
            </w>
            <z>
                <xsl:for-each select="dvm/rows/row/cell[3]">
                    <xsl:if test="generate-id() = generate-id(key('Cells', .)[1])">
                        <item>
                            <xsl:value-of select="."/>
                        </item>
                    </xsl:if>
                </xsl:for-each>
            </z>
        </root>
    </xsl:template>
</xsl:stylesheet>

これにより、次の結果が得られます。

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <w>
        <item>CODE1</item>
        <item>CODE1</item>
        <item>CODE2</item>
    </w>
    <z>
        <item>CODE1</item>
        <item>CODE2</item>
    </z>
</root>

説明:
xsl:key値から構築されたノードの出現ごとにキー値を割り当てmatch / useます -cell[3]注目したい値です。次に、これらすべてのcell[3]値をループして、値が一意の ID (関数を適用することでアクセスできる一意の ID を持っている) を持っているかどうかを確認します (各ノードにはgenerate-id()、同じキー値を持つノードのセットの最初の要素の ID (このセットはkey()関数を使用して選択されます)。Cells現在のノード値にキー値として適用されたときに、処理されたノードがキーによって定義されたノードセットの最初のノードと同じかどうかを効果的にチェックしています。
実際には、インデックス[1]は不要です。これを省略すると、セットの最初の要素で等価性がチェックされるためです。generate-id(..node-set..)ノードセットの最初のノードの ID のみを自動的に生成しますが、インデックスを追加する方が少しきれいです。
これにより、CODE1cell[3] 値が 1 つだけ選択されることに注意してください。
これの実用的なアプリケーションは、上記xsl:variableの要素の内容と等しい内容を持つを定義し<z>(したがって、xsl:for-eachetcetera)、その変数を使用してその中の<item>要素をループし、これらを話しているリストに表示することです。

于 2012-04-17T14:36:21.877 に答える