我有这个XML:
<CombinedResults>
<Results>
<Results>
<AccountNumber>5678</AccountNumber>
<Accounts>
<DomainAccount>
<AccountNumber>1234</AccountNumber>
</DomainAccount>
<DomainAccount>
<AccountNumber>9999</AccountNumber>
</DomainAccount>
<DomainAccount>
<AccountNumber>8888</AccountNumber>
</DomainAccount>
</Accounts>
</Results>
<Results>
<AccountNumber>0427</AccountNumber>
</Results>
<Results>
<AccountNumber>1234</AccountNumber>
<Accounts>
<DomainAccount>
<AccountNumber>5678</AccountNumber>
</DomainAccount>
<DomainAccount>
<AccountNumber>9999</AccountNumber>
</DomainAccount>
<DomainAccount>
<AccountNumber>8888</AccountNumber>
</DomainAccount>
</Accounts>
</Results>
</Results>
</CombinedResults>
我需要创建一个表,其中每行都有AccountNumber值。该表必须同时包含Results / AccountNumber标记的值和Results / Accounts / DomainAccount / AccountNumber标记的值,并且不得重复。
我设法做到了,但是我无法删除重复项。
我的代码是:
<xsl:for-each select="CombinedResults/Results/Results">
<tr>
<td><xsl:value-of select="AccountNumber"/></td>
</tr>
</xsl:for-each>
<xsl:for-each select="CombinedResults/Results/Results/Accounts/DomainAccount">
<tr>
<td><xsl:value-of select="AccountNumber"/></td>
</tr>
</xsl:for-each>
我需要先从Results标记中获取值,然后再从DomainAccount中获取那些值,没有重复项。这是我需要获得的输出:
<tr>
<td>5678</td>
</tr>
<tr>
<td>0427</td>
</tr>
<tr>
<td>1234</td>
</tr>
<tr>
<td>9999</td>
</tr>
<tr>
<td>8888</td>
</tr>
要在XSLT-1.0中获得所需的输出,必须使用一种称为Muenchian Grouping的技术。因此,使用所有值创建一个xsl:key
,然后仅选择xsl:for-each
中的第一项。
实现的XSLT-1.0样式表如下:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="items" match="Results/Results/AccountNumber | Results/Results/Accounts/DomainAccount/AccountNumber" use="text()" />
<xsl:template match="/CombinedResults">
<xsl:for-each select="//AccountNumber[generate-id() = generate-id(key('items',text())[1])]">
<tr>
<td style="text-align:center;">
<xsl:value-of select="."/>
</td>
</tr>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
其输出是:
<tr>
<td style="text-align:center;">5678</td>
</tr>
<tr>
<td style="text-align:center;">1234</td>
</tr>
<tr>
<td style="text-align:center;">9999</td>
</tr>
<tr>
<td style="text-align:center;">8888</td>
</tr>
<tr>
<td style="text-align:center;">0427</td>
</tr>
订购不是您所提到的,但是我不能从您想要的输出中推断出任何订购系统。如果需要其他命令,请在xsl:sort
循环中使用xsl:for-each
。
在XSLT-2.0中,这更容易。您只需要使用xsl:for-each-group
函数:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/CombinedResults">
<xsl:for-each-group select="Results/Results/AccountNumber | Results/Results/Accounts/DomainAccount/AccountNumber" group-by="text()">
<tr>
<td style="text-align:center;">
<xsl:value-of select="current-group()[1]"/>
</td>
</tr>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
结果相同。