XSLT2.0 xsl:for-each-group用法详解.

    xiaoxiao2023-03-24  3

    for-each-group是在XSLT2.0中增加进来的一个标签.其主要作用是对结果进行分组.

    由此增加了current-group()和current-grouping-key()两个内置函数.用于判断当前for-each中元素的序列以及识别号.

    <xs:element name="for-each-group" substitutionGroup="xsl:instruction"> <xs:complexType mixed="true"> <xs:complexContent mixed="true"> <xs:extension base="xsl:versioned-element-type"> <xs:sequence> <xs:element ref="xsl:sort" minOccurs="0" maxOccurs="unbounded"/> <xs:group ref="xsl:sequence-constructor-group" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="select" type="xsl:expression" use="required"/> <xs:attribute name="group-by" type="xsl:expression"/> <xs:attribute name="group-adjacent" type="xsl:expression"/> <xs:attribute name="group-starting-with" type="xsl:pattern"/> <xs:attribute name="group-ending-with" type="xsl:pattern"/> <xs:attribute name="collation" type="xs:anyURI"/> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> 对于xsl:for-each-group来做.select属性是是必选的.

    group-by/group-adjacent/group-starting-with/group-ending-with这四个属性选择其中一个用于赋值current-group()以及current-grouping-key()

    例子:

    source文件:people.xml内容如下:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!-- source of people.xml --> <people> <person sex="female"> <firstname>Jennie</firstname> <lastname>Lin</lastname> </person> <person sex="male"> <firstname>Ricky</firstname> <lastname>Lin</lastname> </person> <person sex="male"> <firstname>Peter</firstname> <lastname>Li</lastname> </person> <person sex="female"> <firstname>Fang</firstname> <lastname>Lin</lastname> </person> <person sex="female"> <firstname>FangFang</firstname> <lastname>Wu</lastname> </person> <person sex="male"> <firstname>Paul</firstname> <lastname>Lin</lastname> </person> </people> 对应的XSLT文件:people.xslt

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:myFunction="http://www.ricky.com/myFunction" exclude-result-prefixes="xs myFunction"> <xsl:output indent="yes"/> <xsl:variable name="people" select="document('people.xml')"/> <!-- Date:2016-09-27 XSLT Processor: Saxon command: java net.sf.saxon.Transform -xsl:people.xslt -it:main -o:people.html --> <xsl:template name="main"> <!-- group-by: sex attribute --> <xsl:result-document href="people-group1.xml"> <people> <xsl:comment> sort the people group by the sex attribute. </xsl:comment> <xsl:for-each-group select="$people/people/person" group-by="@sex"> <!-- sort by sex(female > male) --> <xsl:sort select="current-grouping-key()" order="ascending"/> <sex value="{current-grouping-key()}"> <xsl:for-each select="current-group()"> <xsl:sort select="firstname"/> <xsl:sort select="lastname"/> <person firstname="{firstname}" lastname="{lastname}"/> </xsl:for-each> </sex> </xsl:for-each-group> </people> </xsl:result-document> <!-- group-adjacent : lastname is 'Lin' or other--> <xsl:result-document href="people-group2.xml"> <people> <xsl:comment> sort the people by the lastname. 'Lin' in first group,other in the second group </xsl:comment> <xsl:variable name="sort-people" select="myFunction:sort-people()"/> <xsl:for-each-group select="$sort-people/people/person" group-adjacent="if (normalize-space(lastname) = 'Lin') then ('lin') else ('other')"> <!-- current-grouping-key is either 'lin' or 'other' --> <xsl:sort select="current-grouping-key()"/> <group index="{position()}" group-key="{current-grouping-key()}"> <xsl:for-each select="current-group()"> <person firstname="{firstname}" lastname="{lastname}"/> </xsl:for-each> </group> </xsl:for-each-group> </people> </xsl:result-document> <!-- group-starting-with: lastname start with 'Li' --> <xsl:result-document href="people-group3.xml"> <people> <xsl:for-each-group select="$people/people/person" group-starting-with="*[(position() - 1) mod 4 = 0]"> <group index="{position()}"> <xsl:for-each select="current-group()"> <person firstname='{firstname}' lastname="{lastname}"/> </xsl:for-each> </group> </xsl:for-each-group> </people> </xsl:result-document> <!-- test --> <xsl:variable name="sort-people" select="myFunction:sort-people()"/> <people> <xsl:for-each select="$sort-people/people/person"> <person firstname="{firstname}" lastname="{lastname}"/> </xsl:for-each> </people> </xsl:template> <xsl:function name="myFunction:sort-people"> <!-- sort the people by lastname element. --> <xsl:variable name="sort-people"> <people> <xsl:perform-sort select="$people/people/person"> <xsl:sort select="myFunction:mysort(lastname,'Lin')"/> </xsl:perform-sort> </people> </xsl:variable> <xsl:copy-of select="$sort-people"/> </xsl:function> <xsl:function name="myFunction:mysort" as="xs:integer"> <xsl:param name="node"/> <xsl:param name="value" as="xs:string"/> <xsl:value-of select="if (normalize-space($node) = $value) then 0 else 1"/> </xsl:function> </xsl:stylesheet>

    group-by属性常见的用法是以select序列中的节点的某个属性作为分组的条件.条件相同的节点作为同一个组中的序列. 属性实例执行结果参照生成的:people-group1.xml文件

    group-adjacent属性这通过子定义的方式告诉解析器分组的规则.(不同组的current-grouping-key()可以相同.)如上例中告诉解析器lastname='Lin'的当成一组,其余的当成另一组来对待.注:上面例子中通过两个自定义方法对people中的person进行了重新排序.否则生成结果将不止两个组. 属性实例执行结果参照生成的:people-group2.xml文件

    group-starting-with与group-ending-with的用法有点类似,但是结果相反.group-starting-with告诉解析器判断分组的起点.如上面的例子中告诉解析器当(position() - 1) mod 4 = 0 的条件符合的话那么就分组.其结果就是person节点会每四个为一个组.属性实例执行结果参照生成的:people-group3.xml文件

    转载请注明原文地址: https://ju.6miu.com/read-1202029.html
    最新回复(0)