使用 XSLT 对元素进行排序

Sorting elements using XSLT

我有这个要求来对特定元素进行排序。但我不知道我将如何做到这一点。我尝试了我见过的 XSLT,但无法获得我想要的预期输出。输入XML是这样的:

<SyncCredit xmlns="http://schema.XYZ.com/XYZOAGIS/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" releaseID="9.2" versionID="2.12.3">
  <Data>
    <AccountingNo>ERP_12344</AccountingNo>
    <Credit>
      <Header>
        <Name>Supplier Bank</Name>
        <Date>02-08-2017</Date>
      </Header>
      <Payment>
        <ID>111</ID>
        <Date>02-01-2017</Date>
        <Transaction>
          <BookNo>AA-111</BookNo>
          <Creditor>
            <PartyID>
              <ID schemeName="PassportNo">1000</ID>
            </PartyID>
          </Creditor>
        </Transaction>
        <Transaction>
          <BookNo>AA-111</BookNo>
          <Creditor>
            <PartyID>
              <ID schemeName="TaxIdentificationNo">5000</ID>
            </PartyID>
          </Creditor>
        </Transaction>
      </Payment>
      <Payment>
        <ID>222</ID>
        <Date>02-05-2017</Date>
        <Transaction>
          <BookNo>AA-111</BookNo>
          <Creditor>
            <PartyID>
              <ID schemeName="BankPartyNo">4000</ID>
            </PartyID>
          </Creditor>
        </Transaction>
        <Transaction>
          <BookNo>AA-111</BookNo>
          <Creditor>
            <PartyID>
              <ID schemeName="DriverLicense">2000</ID>
            </PartyID>
          </Creditor>
        </Transaction>
      </Payment>
    </Credit>
  </Data>
</SyncCredit>

我的预期输出应该是这样的:

<SyncCredit xmlns="http://schema.XYZ.com/XYZOAGIS/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" releaseID="9.2" versionID="2.12.3">
  <Data>
    <AccountingNo>ERP_12344</AccountingNo>
    <Credit>
      <Header>
        <Name>Supplier Bank</Name>
        <Date>02-08-2017</Date>
      </Header>
      <Payment>
        <ID>111</ID>
        <Date>02-01-2017</Date>
        <Transaction>
          <BookNo>AA-111</BookNo>
          <Creditor>
            <PartyID>
              <ID schemeName="PassportNo">1000</ID>
            </PartyID>
          </Creditor>
        </Transaction>
      </Payment>
      <Payment>
        <ID>222</ID>
        <Date>02-05-2017</Date>
        <Transaction>
          <BookNo>AA-111</BookNo>
          <Creditor>
            <PartyID>
              <ID schemeName="DriverLicense">2000</ID>
            </PartyID>
          </Creditor>
        </Transaction>
      </Payment>
      <Payment>
        <ID>222</ID>
        <Date>02-05-2017</Date>
        <Transaction>
          <BookNo>AA-111</BookNo>
          <Creditor>
            <PartyID>
              <ID schemeName="BankPartyNo">4000</ID>
            </PartyID>
          </Creditor>
        </Transaction>
      </Payment>
      <Payment>
        <ID>111</ID>
        <Date>02-01-2017</Date>
        <Transaction>
          <BookNo>AA-111</BookNo>
          <Creditor>
            <PartyID>
              <ID schemeName="TaxIdentificationNo">5000</ID>
            </PartyID>
          </Creditor>
        </Transaction>
      </Payment>
    </Credit>
  </Data>
</SyncCredit>

必须对 Creditor/PartyID/ID 个元素进行排序,同时保持其他元素不变。但是,我需要将排序后的 Creditor/PartyID/ID 拆分为每个 <Payment> 节点。我正在使用 XSLT v2.0。虽然,我能够使用我得到的参考中的 <xsl:perform-sort> 正确地对 Creditor/PartyID/ID 进行排序,但我得到的输出是这样的:

<Payment>
  <Transaction xmlns="http://schema.XYZ.com/XYZOAGIS/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <BookNo>AA-111</BookNo>
    <Creditor>
      <PartyID>
        <ID schemeName="PassportNo">1000</ID>
      </PartyID>
    </Creditor>
  </Transaction>
  <Transaction xmlns="http://schema.XYZ.com/XYZOAGIS/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <BookNo>AA-111</BookNo>
    <Creditor>
      <PartyID>
        <ID schemeName="DriverLicense">2000</ID>
      </PartyID>
    </Creditor>
  </Transaction>
  <Transaction xmlns="http://schema.XYZ.com/XYZOAGIS/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <BookNo>AA-111</BookNo>
    <Creditor>
      <PartyID>
        <ID schemeName="BankPartyNo">4000</ID>
      </PartyID>
    </Creditor>
  </Transaction>
  <Transaction xmlns="http://schema.XYZ.com/XYZOAGIS/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <BookNo>AA-111</BookNo>
    <Creditor>
      <PartyID>
        <ID schemeName="TaxIdentificationNo">5000</ID>
      </PartyID>
    </Creditor>
  </Transaction>

这是我的 XSLT,它不完整,因为我不知道如何复制 Header 下的元素,并且 Payment.I 只尝试在 Transaction 元素中执行 XSLT。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xpath-default-namespace="http://schema.XYZ.com/XYZOAGIS/2">
<xsl:output method="xml" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
    <xsl:variable name="Transaction">
        <xsl:perform-sort select="SyncCredit/Data/Credit/Payment/Transaction">
            <xsl:sort data-type="number" select="Creditor/PartyID/ID"/>
        </xsl:perform-sort>
    </xsl:variable>
    <Payment>
        <xsl:copy-of select="$Transaction"/>
    </Payment>
</xsl:template>

提前谢谢你。

如果我理解正确的话,你想做的是:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://schema.XYZ.com/XYZOAGIS/2"
xmlns="http://schema.XYZ.com/XYZOAGIS/2">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="Credit">
    <xsl:copy>
        <xsl:copy-of select="Header"/>
        <xsl:apply-templates select="Payment/Transaction">
            <xsl:sort select="Creditor/PartyID/ID" data-type="number" order="ascending"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

<xsl:template match="Transaction">
    <Payment>
        <xsl:copy-of select="../ID, ../Date, ."/>
    </Payment>
</xsl:template>

</xsl:stylesheet>