0

以下のようなXMLがあります。

<minimums type="table">       
      <minLine>
        <minId>S-4LS16L</minId>
        <catA>5550</catA>
        <catA>1800</catA>      
        <catB>5550</catB>
        <catB>1800</catB>     
        <catC>5550</catC>
        <catC>1800</catC>      
      </minLine>    
      <minLine>
        <minId>S-LOC16L</minId>
        <catA>5660</catA>
        <catA>2400</catA>        
        <catB>5660</catB>
        <catB>2400</catB>           
        <catC>2400</catC>
        <catC>310</catC>      
      </minLine>   
 </minimums>

XSL を使用して、catA、catB、catC などの繰り返し要素をグループ化します。

以下は、私の XSLT の一部です。

 <xsl:key name ="groupElement" match ="*" use="name(.)"/>

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

  <xsl:template match="minLine">  

    <xsl:for-each select="*[generate-id()= generate-id(key('groupElement', name(.)))]">

      <xsl:comment> This is Not get Printed during second match of minLine element</xsl:comment>

    </xsl:for-each>

  </xsl:template>

の最初の試合では、 は正常に動作しています。問題は、2 番目の要素の一致中に が出力されないことです。私は愚かな間違いをしているに違いない。

私はどこで間違っていますか?

4

1 に答える 1

0

ここには 3 つの問題があります。

  1. あなたのキーにはすべての要素が含まれています
  2. generate-id() は、ノードセットの最初のノード (ドキュメント順) のみを取ります
  3. 検索されたノードの最初のノードのみを取得する、generate-id() または count() による単純な「muenchian」グループ化は、ネストされた構造には適していません。

これを「catA」要素で検証すると、問題を簡単に理解できます。
インデックス付きのすべての 'catA' 要素を出力することにより、次のノードのリストを取得します:
<xsl:copy-of select="key('groupElement', 'catA')"/>
->
<catA>5550</catA>
<catA>1800</catA>
<catA>5660</catA>
<catA>2400</catA>

ここで、generate-id()常に最初のノードを取るため、2 番目の 'minLine' 要素の一致中に何も起こらないことが明らかになります。

解決

次の方法で目的を達成できます。

  1. 連続して発生する「minLine/*」子の最初のインデックスのみを作成
  2. インデックス付きの 'minLine/*' の子のみを選択する
<!-- index first of sequentially occurring minLine children -->
<xsl:key name ="minLine_key" match="minLine/*[name() != name(preceding-sibling::*[1])]" use="name()"/>

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

<xsl:template match="minLine">
    <!-- select indexed children: look up nodes by name and test wether current is included in the node-set -->
    <xsl:for-each select="*[count(. | key('minLine_key', name())) = count(key('minLine_key', name()))]">
        <xsl:copy-of select="."/>
    </xsl:for-each>
</xsl:template>
于 2013-10-30T07:44:47.497 に答える