Xslt 使用两个不同的XML文件作为源时是否分组?

Xslt 使用两个不同的XML文件作为源时是否分组?,xslt,xslt-1.0,xslt-grouping,Xslt,Xslt 1.0,Xslt Grouping,我想做的是一个典型的分组,通常可以使用xsl:key完成,但是随着组中的数据位于2个不同的文件中,它变得更加复杂。如何处理? 这是我想做的一个例子,我可以请求你的帮助吗?必须符合xslt-1.0 bookreference.xml: <t> <book isbn="1"> <category>SF</category> </book> <book isbn="2">

我想做的是一个典型的分组,通常可以使用xsl:key完成,但是随着组中的数据位于2个不同的文件中,它变得更加复杂。如何处理? 这是我想做的一个例子,我可以请求你的帮助吗?必须符合xslt-1.0

bookreference.xml:

<t>  
    <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>
</t>  

正如我在评论中所建议的,您可以首先将两个文档合并到一个结果树片段中,然后使用exsl:node set获取一个节点集,然后在该节点集上应用Muenchian分组:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exsl="http://exslt.org/common"
  exclude-result-prefixes="exsl"
  version="1.0">

  <xsl:param name="price-url" select="'test2011113002.xml'"/>
  <xsl:variable name="doc2" select="document($price-url)"/>

  <xsl:output method="text"/>

  <xsl:variable name="rtf">
    <xsl:apply-templates select="//book" mode="merge"/>
  </xsl:variable>

  <xsl:template match="book" mode="merge">
    <xsl:copy>
      <xsl:variable name="isbn" select="@isbn"/>
      <xsl:copy-of select="@* | node()"/>
      <xsl:for-each select="$doc2">
        <xsl:copy-of select="key('k1', $isbn)/price"/>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>

  <xsl:key name="k1" match="book" use="@isbn"/>
  <xsl:key name="k2" match="book" use="category"/>

  <xsl:template match="/">
    <xsl:apply-templates select="exsl:node-set($rtf)/book[generate-id() = generate-id(key('k2', category)[1])]"/>
  </xsl:template>

  <xsl:template match="book">
    <xsl:variable name="current-group" select="key('k2', category)"/>
    <xsl:value-of select="concat($current-group/category, ': ', count($current-group), ' - Total : ', sum($current-group/price), '&#10;')"/>
  </xsl:template>

</xsl:stylesheet>

问得好,+1

不需要复杂的(超出需要的)分组或任何扩展功能

<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="kPriceByIsbn" match="price"
      use="../@isbn"/>

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

 <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:value-of select="count($vBooksinCat)"/>
     <xsl:text> book(s) - Total : $</xsl:text>

     <xsl:for-each select="$vMyLib">
      <xsl:value-of select="sum(key('kPriceByIsbn', $vBooksinCat/@isbn))"/>
      <xsl:text>&#xA;</xsl:text>
     </xsl:for-each>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
SF : 3 book(s) - Total : $40
Comedy : 2 book(s) - Total : $5

一个可能的XSLT1.0过程是首先将两个文档合并成一个结果树片段,然后使用扩展函数(如exsl:node set)将结果树片段转换成一个节点集,然后可以像往常一样在该节点集上使用Muenchian分组。那么,您的目标是哪个XSLT 1.0处理器,它是否有exsl:node set或类似的设置?嗨,Martin,XSLT 1.0处理器是XSLT 1.0。所以这肯定没问题,我将尝试一下你的方法。为什么你提供格式不正确的XML?提供的两个片段中的每一个都至少有两个问题。请编辑并更正。@_Dimitre:我为错误的XML表示歉意:修复完成。@_Martin:这可以做得非常简单,没有任何扩展函数。@_Dimitre:感谢您的解决方案,并就错误的XML向我提出建议。@_Dimitre:研究您的代码后,事实上,它不符合要求,因为我认为我不清楚如何解释我的需求。我想按家庭获得我的图书馆组中图书的数量和总价,而不是按家庭获得参考资料组中图书的完整定价和数量。我对示例进行了修改,使其更为明确。@Seb:我的答案与您的问题中提供的结果完全一致——在您10分钟前更改它之前!如果你有一个新问题——问一个新问题。你的问题已经完全回答了。此外,在你的问题文本中没有提到“家庭”,因此你的评论与之相矛盾。什么是“家庭”?请停止修改此问题,接受最佳答案并提出新问题。顺便说一下,我认为我的答案中的解决方案即使是对修改后的问题也会产生正确的结果。@@Dimitre:family=category。在编辑之前和之后,我的喜剧类别=>喜剧:1本书-总计:5美元,因为我的库中只有1本喜剧书。我修改了相关输出,以匹配两者的结果,我接受答案,因为它是有用的(在任何其他论坛上都没有看到),并将打开一个新问题,更生动地解释我的需求。
<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="kPriceByIsbn" match="price"
      use="../@isbn"/>

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

 <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:value-of select="count($vBooksinCat)"/>
     <xsl:text> book(s) - Total : $</xsl:text>

     <xsl:for-each select="$vMyLib">
      <xsl:value-of select="sum(key('kPriceByIsbn', $vBooksinCat/@isbn))"/>
      <xsl:text>&#xA;</xsl:text>
     </xsl:for-each>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
<t>
    <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>
</t>
SF : 3 book(s) - Total : $40
Comedy : 2 book(s) - Total : $5