[英]XSLT 1.0 to sort and group an XML
I need an XSLT 1.0 that converts the following XML. 我需要一个XSLT 1.0,它可以转换以下XML。
<Record>
<Row>
<Name>AAA</Name>
<Surname>Surname1</Surname>
</Row>
<Row>
<Name>BBB</Name>
<Surname>Surname2</Surname>
</Row>
<Row>
<Name>CCC</Name>
<Surname>Surname1</Surname>
</Row>
<Row>
<Name>DDD</Name>
<Surname>Surname2</Surname>
</Row>
<Row>
<Name>EEE</Name>
<Surname>Surname1</Surname>
</Row>
<Row>
<Name>FFF</Name>
<Surname>Surname2</Surname>
</Row>
<Row>
<Name>GGG</Name>
<Surname>Surname1</Surname>
</Row>
<Row>
<Name>HHH</Name>
<Surname>Surname2</Surname>
</Row>
</Record>
The output I am expecting is: 我期望的输出是:
<Output>
<Recordset1>
<Record>
<Name>AAA</Name>
<Surname>Surname1</Surname>
</Record>
<Record>
<Name>CCC</Name>
<Surname>Surname1</Surname>
</Record>
</Recordset1>
<Recordset1>
<Record>
<Name>EEE</Name>
<Surname>Surname1</Surname>
</Record>
<Record>
<Name>GGG</Name>
<Surname>Surname1</Surname>
</Record>
</Recordset1>
<Recordset2>
<Record>
<Name>BBB</Name>
<Surname>Surname2</Surname>
</Record>
<Record>
<Name>DDD</Name>
<Surname>Surname2</Surname>
</Record>
</Recordset2>
<Recordset2>
<Record>
<Name>FFF</Name>
<Surname>Surname2</Surname>
</Record>
<Record>
<Name>HHH</Name>
<Surname>Surname2</Surname>
</Record>
</Recordset2>
</Output>
The conditions are: 条件是:
Recordset1 should contain Surname1 nodes Recordset1应包含Surname1节点
Recordset2 should contain Surname2 nodes Recordset2应包含Surname2节点
Output should be sorted by Surname 输出应按姓氏排序
There is a maximum of 2 Records per Recordset. 每个记录集最多有2条记录。
This may help you. 这可能对您有帮助。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxml">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key match="Row" name="rows" use="Surname"/>
<xsl:template match="Record">
<Output>
<xsl:for-each select="Row[generate-id(.) = generate-id(key('rows', Surname)[1])]">
<xsl:sort select="Surname" data-type="text" order="ascending"/>
<xsl:variable name="Recordset" select="concat('Recordset',position())"/>
<xsl:variable name="Rows">
<xsl:copy-of select="key('rows', Surname)"/>
</xsl:variable>
<xsl:variable name="RowList" select="msxml:node-set($Rows)"/>
<xsl:for-each select="$RowList/Row[position() mod 2 = 1]">
<xsl:element name="{$Recordset}">
<Record>
<xsl:copy-of select="./*"/>
</Record>
<xsl:if test="following-sibling::Row[1]/*">
<Record>
<xsl:copy-of select="following-sibling::Row[1]/*"/>
</Record>
</xsl:if>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</Output>
</xsl:template>
</xsl:stylesheet>
There were a few tricks to this: 有一些技巧:
This stylesheet solves those problems: 此样式表解决了这些问题:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Record">
<Output>
<xsl:apply-templates select="//Row[not(./Surname=preceding::Surname)]/Surname" mode="group">
<xsl:sort select="Surname" />
</xsl:apply-templates>
</Output>
</xsl:template>
<xsl:template match="Surname" mode="group">
<xsl:variable name="surname" select="./text()" />
<xsl:variable name="surnameIndex" select="position()" />
<xsl:variable name="surnameGroup" select="/Record/Row[Surname/text()=$surname]" />
<xsl:for-each select="$surnameGroup">
<xsl:variable name="index" select="position()" />
<!-- only create a new record set on the first (or only) member of the output pair -->
<xsl:if test="$index mod 2=1"> <!-- positions are 1 based, not 0 based -->
<xsl:element name="Recordset{$surnameIndex}">
<!-- alternatively, use xsl:copy-of -->
<xsl:apply-templates select="$surnameGroup[$index]" mode="record" />
<xsl:apply-templates select="$surnameGroup[$index+1]" mode="record" />
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="Row" mode="record">
<Record>
<Name><xsl:value-of select="Name" /></Name>
<Surname><xsl:value-of select="Surname" /></Surname>
</Record>
</xsl:template>
</xsl:stylesheet>
The output of applying this stylesheet against your input document is: 对您的输入文档应用此样式表的输出为:
<?xml version="1.0" encoding="UTF-8" ?>
<Output>
<Recordset1>
<Record>
<Name>AAA</Name>
<Surname>Surname1</Surname>
</Record>
<Record>
<Name>CCC</Name>
<Surname>Surname1</Surname>
</Record>
</Recordset1>
<Recordset1>
<Record>
<Name>EEE</Name>
<Surname>Surname1</Surname>
</Record>
<Record>
<Name>GGG</Name>
<Surname>Surname1</Surname>
</Record>
</Recordset1>
<Recordset2>
<Record>
<Name>BBB</Name>
<Surname>Surname2</Surname>
</Record>
<Record>
<Name>DDD</Name>
<Surname>Surname2</Surname>
</Record>
</Recordset2>
<Recordset2>
<Record>
<Name>FFF</Name>
<Surname>Surname2</Surname>
</Record>
<Record>
<Name>HHH</Name>
<Surname>Surname2</Surname>
</Record>
</Recordset2>
</Output>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.