带密钥的xslt 1.0组

时间:2017-06-23 10:50:37

标签: xslt xpath

我有源XML文件

<?xml version="1.0" encoding="utf-8"?>
<Main>
    <BusinessPartner>
        <ID>2000000270</ID>
        <Role>FLVN01</Role>
    </BusinessPartner>
    <BusinessPartner>
        <ID>2000000299</ID>
        <Role>FLVN01</Role>
    </BusinessPartner>
    <BusinessPartner>
        <ID>2000000299</ID>
        <Role>FLVN00</Role>
    </BusinessPartner>
    <BusinessPartner>
        <ID>2000000299</ID>
        <Role>FLVN00</Role>
    </BusinessPartner>
</Main>

我正在尝试将其转换为以下XML。它按ID分组,并且只留下不同的Role s。

<Main>
   <bp>
      <ID>2000000270</ID>
      <Role>
        <RoleCode>FLVN00</RoleCode>
      </Role>
    </bp>

    <bp>
      <ID>2000000299</ID>
      <Role>
        <RoleCode>FLVN00</RoleCode>
      </Role>
      <Role>
        <RoleCode>FLVN01</RoleCode>
      </Role>
    </bp>
</Main>

我尝试过以下XSLT代码,但每个ID只输出一个角色。

  <xsl:key name="kBpByID" match="BusinessPartner" use="ID" />
    <xsl:for-each select="key('kBpByID', ID)">
      <bp>
        <xsl:sort select="./Role" />
        <xsl:if test="not(./Role = preceding-sibling::BusinessPartner[1]/Role)">
              <ID>
                 <xsl:value-of select="ID"/>
              </ID
              <Role>
            <RoleCode>
                <xsl:value-of select="Role" />
                </RoleCode>
              </Role>
          </xsl:if>
      </xsl:for-each>
    </bp>

我该如何解决?

1 个答案:

答案 0 :(得分:0)

这里需要两把钥匙。一个按目前的BusinessPartner获取ID元素

  <xsl:key name="kBpByID" match="BusinessPartner" use="ID"/>

然后根据角色为每个不同的ID

获取BusinessPartner
  <xsl:key name="kBpByIDAndRole" match="BusinessPartner" use="concat(ID, '|', Role)"/>

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html" indent="yes"/>

  <xsl:key name="kBpByID" match="BusinessPartner" use="ID"/>
  <xsl:key name="kBpByIDAndRole" match="BusinessPartner" use="concat(ID, '|', Role)"/>

  <xsl:template match="Main">
    <xsl:for-each select="BusinessPartner[generate-id() = generate-id(key('kBpByID', ID)[1])]">
      <bp>
        <ID>
          <xsl:value-of select="ID"/>
        </ID>
        <xsl:for-each select="key('kBpByID', ID)[generate-id() = generate-id(key('kBpByIDAndRole', concat(ID, '|', Role))[1])]">
          <xsl:sort select="Role"/>
          <Role>
            <RoleCode>
              <xsl:value-of select="Role"/>
            </RoleCode>
          </Role>
        </xsl:for-each>
      </bp>
    </xsl:for-each>
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>