2

これは、ここでの私の質問の進化です 。sql group-byのように2つのxmlファイルをグループ化します 。例とDimitreSolutionは、個別のisbn値をカウントしていました。次に、ライブラリxmlを変更してmylibrary.xmlを作成します。

<library>  
   <book id="1" isbn="1"/>
   <book id="2" isbn="1"/>
   <book id="3" isbn="2"/>
   <book id="4" isbn="4"/>
   <book id="5" isbn="5"/>
   <book id="6" isbn="4"/>
   <book id="7" isbn="4"/>   
</library>  

そしてこれを使用することができます:bookreference.xml:

<reference>  
    <book isbn="1">  
        <category>SF</category>  
    </book>  
    <book isbn="2">  
        <category>SF</category>  
    </book>  
    <book isbn="3">  
        <category>SF</category>  
    </book>  
    <book isbn="4">  
        <category>Comedy</category>  
    </book>  
    <book isbn="5">  
        <category>Comedy</category>  
    </book>
</reference>  

xslt 1-0を使用して、mylibraryで取得した本の数を'同じisbn'、groupbyカテゴリでも取得したい。

出力が欲しかった:

SF : 3 book(s) 
Comedy : 4 book(s) 

私のxsltはここで提案します:sql group-byのように2つのxmlファイルをグループ化します-正常に動作しますが、もちろん「for-each」ループと拡張関数を使用します。確かにもっと良い解決策があります。

4

3 に答える 3

1

このために動作するようにDimitriバージョンを変更しました

<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="kBookByCat" match="book" use="category"/>

<xsl:variable name="vRef" select="document('file:///c:/temp/delete/reference.xml')"/>

<xsl:variable name="meh" select="*"/>

<xsl:template match="/">
    <xsl:apply-templates select="$vRef/reference/book[generate-id()=generate-id(key('kBookByCat', category)[1])]" />
</xsl:template>

<xsl:template match="book">
    <xsl:variable name="cat" select="category"/>
    <xsl:value-of select="category"/> : <xsl:text/>
    <xsl:variable name="isbns" select="$vRef/reference/book[category=$cat]/@isbn"/>
    <xsl:value-of select="count($meh/book[@isbn=$isbns])"/>
    <xsl:text> book(s)&#xA;</xsl:text>
</xsl:template>
于 2011-12-02T14:00:11.670 に答える
1

再び非常に良い質問です!(+1)

完全な効率を達成するための2つのキーを使用したこの変換

<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="kBookByCat" match="book"
          use="category"/>

     <xsl:key name="kBookByIsbn" match="book"
          use="@isbn"/>

     <xsl:variable name="vDoc" select="/"/>

     <xsl:variable name="vRef" select=
     "document('file:///c:/temp/delete/reference.xml')"/>

     <xsl:variable name="vMyIsbns" select="/*/*/@isbn"/>

     <xsl:variable name="vResult">
      <xsl:apply-templates select="$vRef/*"/>
     </xsl:variable>

     <xsl:template match="/">
      <xsl:copy-of select="$vResult"/>
     </xsl:template>

     <xsl:template match=
      "book[generate-id()
           =
            generate-id(key('kBookByCat', category)[1])
            ]
      ">
         <xsl:variable name="vBooksinCat" select=
              "key('kBookByCat', category)"/>

         <xsl:value-of select="category"/> : <xsl:text/>
         <xsl:for-each select="$vDoc">
           <xsl:value-of select="count(key('kBookByIsbn',$vBooksinCat/@isbn))"/>
         </xsl:for-each>
         <xsl:text> book(s)&#xA;</xsl:text>
     </xsl:template>
     <xsl:template match="text()"/>
</xsl:stylesheet>

mylibrary.xmlファイルに含まれている提供されたXMLドキュメントに適用された場合

<library>
   <book id="1" isbn="1"/>
   <book id="2" isbn="1"/>
   <book id="3" isbn="2"/>
   <book id="4" isbn="4"/>
   <book id="5" isbn="5"/>
   <book id="6" isbn="4"/>
   <book id="7" isbn="4"/>
</library>

そして、これがC:\ temp \ delete \ reference.xmlにXMLドキュメントを提供している

<reference>
    <book isbn="1">
        <category>SF</category>
    </book>
    <book isbn="2">
        <category>SF</category>
    </book>
    <book isbn="3">
        <category>SF</category>
    </book>
    <book isbn="4">
        <category>Comedy</category>
    </book>
    <book isbn="5">
        <category>Comedy</category>
    </book>
</reference>

必要な正しい出力を生成します

SF : 3 book(s)
Comedy : 4 book(s)
于 2011-12-02T14:09:27.240 に答える
0

素晴らしいディミトリの反応に加えて、mylibraryに0冊の本が設定されている本のカテゴリを印刷しないように次のことを提案します。

<xsl:variable name="catname" select="category"/>
<xsl:for-each select="$vDoc">
    <xsl:variable name="cnt" select="count(key('kBookByIsbn',$vBooksinCat/@isbn))"/>
    <xsl:if test="$cnt &gt; 0">
        <xsl:value-of select="$catname"/> : 
        <xsl:text/>
        <xsl:value-of select="$cnt"/>
        <xsl:text> book(s)&#xA;</xsl:text>
    </xsl:if>
</xsl:for-each>
于 2011-12-02T19:44:07.417 に答える