0

filt次のようなxmlを保持する という名前の変数があります。

<filters>
  <ISP_WebItem FILTER="Farve" FILTERNAME="Transparent" UNITCODE="" />
  <ISP_WebItem FILTER="Antal" FILTERNAME="10" UNITCODE="mapper" />
  <ISP_WebItem FILTER="Indpakning" FILTERNAME="Æske" UNITCODE="" />
  <ISP_WebItem FILTER="Materiale" FILTERNAME="PP" UNITCODE="" />
  <ISP_WebItem FILTER="Bredde" FILTERNAME="35.6" UNITCODE="cm" />
  <ISP_WebItem FILTER="Farve" FILTERNAME="blue" UNITCODE="" />
  <ISP_WebItem FILTER="Dybde" FILTERNAME="5" UNITCODE="mm" />
  <ISP_WebItem FILTER="Farve" FILTERNAME="red" UNITCODE="" />
</filters>

これらの要素を「FILTER」属性でグループ化したいと考えています。つまり、このような出力 xml が必要です (xml 要素はフィルター属性によって再配置されることに注意してください。つまり、farve として FILTER を持つすべての要素が隣接する位置にあることに注意してください)

<filters>
  <ISP_WebItem FILTER="Farve" FILTERNAME="Transparent" UNITCODE="" />
  <ISP_WebItem FILTER="Farve" FILTERNAME="blue" UNITCODE="" />
  <ISP_WebItem FILTER="Farve" FILTERNAME="red" UNITCODE="" />
  <ISP_WebItem FILTER="Antal" FILTERNAME="10" UNITCODE="mapper" />
  <ISP_WebItem FILTER="Indpakning" FILTERNAME="Æske" UNITCODE="" />
  <ISP_WebItem FILTER="Materiale" FILTERNAME="PP" UNITCODE="" />
  <ISP_WebItem FILTER="Bredde" FILTERNAME="35.6" UNITCODE="cm" />
  <ISP_WebItem FILTER="Dybde" FILTERNAME="5" UNITCODE="mm" />
</filters>

私はこのようなことを試しました:

  <xsl:variable name="grouped_filt" select="$filt//ISP_WebItem[@FILTER = preceding-sibling::*[1]/@FILTER ]"></xsl:variable>

しかし役に立たない。私はこれで何か間違ったことを見つけることができません。誰でも助けることができますか?

4

1 に答える 1

1

これに対する XSLT 1.0 での標準的なアプローチはMuenchian Groupingと呼ばれます。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes" />
  <xsl:key name="itemByFilter" match="ISP_WebItem" use="@FILTER" />

  <xsl:template match="filters">
    <filters>
      <xsl:apply-templates select="ISP_WebItem[
          generate-id() = generate-id(key('itemByFilter', @FILTER)[1])]" />
    </filters>
  </xsl:template>

  <xsl:template match="ISP_WebItem">
    <xsl:copy-of select="key('itemByFilter', @FILTER)" />
  </xsl:template>
</xsl:stylesheet>

これは、各値を持つ最初のgenerate-id() = generate-id(key('itemByFilter', @FILTER)[1])要素だけを選択し、その要素にテンプレートを適用する方法です。テンプレートでは、同じ値を持つすべての要素をコピーします。 ISP_WebItemFILTERISP_WebItemFILTER

編集:

<filters>要素は、入力ドキュメントから直接一致させるものではなく、「filt という名前の変数」にあると言います。その場合、同じキー定義を使用できます

  <xsl:key name="itemByFilter" match="ISP_WebItem" use="@FILTER" />

代わりに<xsl:template match="filters">を使用します<xsl:for-each select="$filt/filters">filt変数がノード セットではなく結果ツリー フラグメントである場合 - つまり、次のように作成された場合

<xsl:variable name="filt">
  <filters>
    <!-- ... -->
  </filters>
</xsl:variable>

ノードセットに戻すには拡張機能が必要です

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                xmlns:exslt="http://exslt.org/common"
                exclude-result-prefixes="exslt">
  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes" />
  <xsl:key name="itemByFilter" match="ISP_WebItem" use="@FILTER" />


  <xsl:variable name="filt">
    <filters>
      <ISP_WebItem FILTER="Farve" FILTERNAME="Transparent" UNITCODE="" />
      <ISP_WebItem FILTER="Antal" FILTERNAME="10" UNITCODE="mapper" />
      <ISP_WebItem FILTER="Farve" FILTERNAME="blue" UNITCODE="" />
    </filters>
  </xsl:variable>

  <xsl:variable name="grouped_filt">
    <xsl:for-each select="exslt:node-set($filt)/filters">
      <filters>
        <xsl:apply-templates select="ISP_WebItem[
            generate-id() = generate-id(key('itemByFilter', @FILTER)[1])]" />
      </filters>
    </xsl:for-each>
  </xsl:variable>

  <xsl:template match="/">
    <!-- Demonstrate that the grouping did the right thing -->
    <xsl:copy-of select="$grouped_filt" />
  </xsl:template>

  <xsl:template match="ISP_WebItem">
    <xsl:copy-of select="key('itemByFilter', @FILTER)" />
  </xsl:template>
</xsl:stylesheet>

このスタイル シートは、任意の入力ドキュメント (例: <foo/>) に対して実行すると出力されます。

<?xml version="1.0"?>
<filters>
  <ISP_WebItem FILTER="Farve" FILTERNAME="Transparent" UNITCODE=""/>
  <ISP_WebItem FILTER="Farve" FILTERNAME="blue" UNITCODE=""/>
  <ISP_WebItem FILTER="Antal" FILTERNAME="10" UNITCODE="mapper"/>
</filters>
于 2013-01-02T12:03:31.567 に答える