2012-04-10 12 views
1

XSLTを使用してXMLエントリをグループ化する際に問題があります。ここでfor-eachループの最初の要素がxsltの先行兄弟で欠落しています

は、私のソースXMLです:

<chron> 
<chronEntry type="education" order="1" blockorder="1"> 
    <foo>bar</foo> 
</chronEntry> 
    <chronEntry type="education" order="2" blockorder="1"> 
<foo>bar</foo> 
    </chronEntry> 
<chronEntry type="education" order="3" blockorder="1"> 
    <foo>bar</foo> 
</chronEntry> 
<chronEntry type="communityservice" order="1" blockorder="2"> 
    <foo>bar</foo> 
</chronEntry> 
<chronEntry type="experience" order="1" blockorder="3"> 
    <foo>bar</foo> 
</chronEntry> 
<chronEntry type="experience" order="2" blockorder="3"> 
    <foo>bar</foo> 
</chronEntry> 
<chronEntry type="experience" order="3" blockorder="3"> 
    <foo>bar</foo> 
</chronEntry> 
<chronEntry type="experience" order="4" blockorder="3"> 
    <foo>bar</foo> 
</chronEntry> 
</chron> 

私が取得したいどのような属性の「タイプ」の利用可能なすべての値のリストです。この場合は、次のようになります。 - 教育 - communityservice - 経験

私はこのようにそれをしようと試み:私が得る

<xsl:for-each select="/foobar/chron/chronEntry"> 
      <xsl:sort select="@blockorder"/> 
       <xsl:if test ="@blockorder != preceding-sibling::chronEntry[1]/@blockorder"> 
        <fo:table-row> 
         <fo:table-cell> 
          <fo:block><xsl:value-of select="@type"/></fo:block> 
         </fo:table-cell> 
        </fo:table-row> 
       </xsl:if> 
      </xsl:for-each> 

何がある: - communityservice - 経験

私は」私はそれを得るために何ができますか?

あなたの助けのためのタク!

Greetz

デイブ

+0

あなたは:ソート、あなたがこれを使用することができた場合、テストXSLT 1.0またはXSLT 2.0を使用していますか? –

答えて

1

問題は、ソートされたノード・リストを作成しているが、preceding-sibling::(または軸)のみならずに(文書内のノード間の関係を表現するために使用することができることですノードリスト)。

したがって、preceding-sibling:: chronEntry [1]は、現在のドキュメントのコンテキストノードselects the first preceding sibling chronEntry` - ないソートノードリストです。

ソリューション:XSLT 1.0で

  1. 変数にxsl:for-eachの結果をキャプチャします。これは悪名高いRTFタイプであるため、使用中のXSLT 1.0プロセッサでサポートされているxxx:node-set()拡張機能を使用して、それを通常のツリーに変換する必要があります。そして、この規則的な木の中で、preceding-sibling::を含む軸は、必要な意味を持ちます。

  2. 推奨溶液。このような

:Muenchianグループ化を使用して指名手配、正しい結果がを生産している

<chron> 
    <chronEntry type="education" order="1" blockorder="1"> 
     <foo>bar</foo> 
    </chronEntry> 
    <chronEntry type="education" order="2" blockorder="1"> 
     <foo>bar</foo> 
    </chronEntry> 
    <chronEntry type="education" order="3" blockorder="1"> 
     <foo>bar</foo> 
    </chronEntry> 
    <chronEntry type="communityservice" order="1" blockorder="2"> 
     <foo>bar</foo> 
    </chronEntry> 
    <chronEntry type="experience" order="1" blockorder="3"> 
     <foo>bar</foo> 
    </chronEntry> 
    <chronEntry type="experience" order="2" blockorder="3"> 
     <foo>bar</foo> 
    </chronEntry> 
    <chronEntry type="experience" order="3" blockorder="3"> 
     <foo>bar</foo> 
    </chronEntry> 
    <chronEntry type="experience" order="4" blockorder="3"> 
     <foo>bar</foo> 
    </chronEntry> 
</chron> 

:この変換が提供されるXML文書に適用され

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

<xsl:key name="kType" match="@type" use="."/> 

<xsl:template match= 
    "chronEntry 
    [generate-id(@type) 
    = 
    generate-id(key('kType', @type)[1]) 
    ]"> 
    <xsl:value-of select="concat(@type, ' ')"/> 
</xsl:template> 
<xsl:template match="text()"/> 
</xsl:stylesheet> 

education communityservice experience 
0

本当にxsl:sortが必要ですか?それともグループ分けに使ったのですか?あなたのXSLを並べ替えをして修正します:それはそうであるならば、あなただけのXSLを削除することができますが、XSLが必要な場合は

 <xsl:for-each select="/foobar/chron/chronEntry"> 
      <xsl:if test ="not(@blockorder = preceding-sibling::chronEntry/@blockorder)"> 
       <fo:table-row> 
        <fo:table-cell> 
         <fo:block><xsl:value-of select="@type"/></fo:block> 
        </fo:table-cell> 
       </fo:table-row> 
      </xsl:if> 
     </xsl:for-each> 

は:

 <xsl:variable name="types" select="/foobar/chron/chronEntry[not(preceding-sibling::*/@[email protected])]"/> 
     <xsl:for-each select="$types"> 
      <xsl:sort select="@blockorder"/> 
      <fo:table-row> 
       <fo:table-cell> 
        <fo:block> 
         <xsl:value-of select="@type"/> 
        </fo:block> 
       </fo:table-cell> 
      </fo:table-row> 
     </xsl:for-each> 
関連する問題