XSLT将来自2个不同标签的数据分组并删除重复项

问题描述 投票:0回答:1

我有这个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>
html xml xslt
1个回答
0
投票

要在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>

结果相同。

© www.soinside.com 2019 - 2024. All rights reserved.