Muenchian分组-在一个节点内进行分组,而不是在整个文档中进行分组 [英] Muenchian Grouping - group within a node, not within the entire document

查看:98
本文介绍了Muenchian分组-在一个节点内进行分组,而不是在整个文档中进行分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在XSLT中使用Muenchian分组对匹配的节点进行分组,但是我只想在父节点内进行分组,而不是在整个源XML文档中进行分组.

I'm trying to use Muenchian grouping in my XSLT to group matching nodes, but I only want to group within a parent node, not across the entire source XML document.

给出如下XSLT和XML(为示例代码的长度致歉):

Given XSLT and XML as follows (apologies for the length of my sample code):

XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
 <xsl:output method="html" indent="yes"/>

 <xsl:key name="contacts-by-surname" match="contact" use="surname" />
 <xsl:template match="records">
  <xsl:for-each select="contact[count(. | key('contacts-by-surname', surname)[1]) = 1]">
   <xsl:sort select="surname" />
   <xsl:value-of select="surname" />,<br />
   <xsl:for-each select="key('contacts-by-surname', surname)">
    <xsl:sort select="forename" />
    <xsl:value-of select="forename" /> (<xsl:value-of select="title" />)<br />
   </xsl:for-each>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

XML

<root>
 <records>
  <contact id="0001">
   <title>Mr</title>
   <forename>John</forename>
   <surname>Smith</surname>
  </contact>
  <contact id="0002">
   <title>Dr</title>
   <forename>Amy</forename>
   <surname>Jones</surname>
  </contact>
  <contact id="0003">
   <title>Mrs</title>
   <forename>Mary</forename>
   <surname>Smith</surname>
  </contact>
  <contact id="0004">
   <title>Ms</title>
   <forename>Anne</forename>
   <surname>Jones</surname>
  </contact>
  <contact id="0005">
   <title>Mr</title>
   <forename>Peter</forename>
   <surname>Smith</surname>
  </contact>
  <contact id="0006">
   <title>Dr</title>
   <forename>Indy</forename>
   <surname>Jones</surname>
  </contact>
 </records>
 <records>
  <contact id="0001">
   <title>Mr</title>
   <forename>James</forename>
   <surname>Smith</surname>
  </contact>
  <contact id="0002">
   <title>Dr</title>
   <forename>Mandy</forename>
   <surname>Jones</surname>
  </contact>
  <contact id="0003">
   <title>Mrs</title>
   <forename>Elizabeth</forename>
   <surname>Smith</surname>
  </contact>
  <contact id="0004">
   <title>Ms</title>
   <forename>Sally</forename>
   <surname>Jones</surname>
  </contact>
  <contact id="0005">
   <title>Mr</title>
   <forename>George</forename>
   <surname>Smith</surname>
  </contact>
  <contact id="0006">
   <title>Dr</title>
   <forename>Harry</forename>
   <surname>Jones</surname>
  </contact>
 </records>
</root>

结果

Jones,
Amy (Dr)
Anne (Ms)
Harry (Dr)
Indy (Dr)
Mandy (Dr)
Sally (Ms)

Smith,
Elizabeth (Mrs)
George (Mr)
James (Mr)
John (Mr)
Mary (Mrs)
Peter (Mr)

如何将每个<records>分组,以实现以下结果:

How do I group within each <records> and achieve this result:

Jones,
Amy (Dr)
Anne (Ms)
Indy (Dr)

Smith,
John (Mr)
Mary (Mrs)
Peter (Mr)

Jones,
Harry (Dr)
Mandy (Dr)
Sally (Ms)

Smith,
Elizabeth (Mrs)
George (Mr)
James (Mr)

推荐答案

花了我些时间...我本来打算放弃,但仍然继续:)

Took me some time ... I was about to give up but continued nevertheless :)

key函数的缺点是生成的密钥将始终用于整个xml.因此,您应该在密钥中串联其他信息以使其更加具体.在例如在下面,我将连接记录"节点的位置,以便获得每个记录的不同姓氏的键.

The drawback of the key function is that the key generated will always be for the entire xml. Hence you should concatenate additional information in your key to make it more specific. In the e.g. below, I am concatenating the position of records node, so that I get keys for distinct surnames per records.

这是xslt:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="html" indent="yes"/>
  <xsl:key name="distinct-surname" match="contact" use="concat(generate-id(..), '|', surname)"/>
  <xsl:template match="records">
    <xsl:for-each select="contact[generate-id() = generate-id(key('distinct-surname', concat(generate-id(..), '|', surname))[1])]">
      <xsl:sort select="surname" />
      <xsl:value-of select="surname" />,<br />
      <xsl:for-each select="key('distinct-surname', concat(generate-id(..), '|', surname))">
        <xsl:sort select="forename" />
        <xsl:value-of select="forename" /> (<xsl:value-of select="title" />)<br />
      </xsl:for-each>
    </xsl:for-each>
  </xsl:template>  
</xsl:stylesheet>

这是结果:

Jones,
Amy (Dr)
Anne (Ms)
Indy (Dr)
Smith,
John (Mr)
Mary (Mrs)
Peter (Mr)
Jones,
Harry (Dr)
Mandy (Dr)
Sally (Ms)
Smith,
Elizabeth (Mrs)
George (Mr)
James (Mr)

请注意,结果也按形式排序.如果您不想按空格排序,则需要删除<xsl:sort select="forename" />

Please note that the result is sorted on the forenames too. If you don't want to sort it on forenames, you need to remove the line <xsl:sort select="forename" />

这篇关于Muenchian分组-在一个节点内进行分组,而不是在整个文档中进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆