如何在比较中使用子节点合并重复节点?
How do I merge duplicate nodes, using children in the comparison?
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="Test1.xsl"?>
<root>
<RemittanceInformation>
<EntityAssignedNumber>25</EntityAssignedNumber>
<IndividualRemittance>
<IndividualName>
<LastName>Johnson</LastName>
<FirstName>Steve</FirstName>
<ExchangeAssignedSubscriberID>6650442525</ExchangeAssignedSubscriberID>
</IndividualName>
<ExchangeAssignedQHPID>38408SC221000101</ExchangeAssignedQHPID>
<ExchangeAssignedPolicyID>26141334</ExchangeAssignedPolicyID>
<IssuerAssignedPolicyID>39147964</IssuerAssignedPolicyID>
<IssuerAssignedSubscriberID>101009913000</IssuerAssignedSubscriberID>
</IndividualRemittance>
<RemittanceDetail>
<ExchangePaymentCode>APTC</ExchangePaymentCode>
<PaymentAmount>214.00</PaymentAmount>
<PaymentCoverageStartDate>2016-10-01</PaymentCoverageStartDate>
<PaymentCoverageEndDate>2016-10-31</PaymentCoverageEndDate>
</RemittanceDetail>
<RemittanceDetail>
<ExchangePaymentCode>UF</ExchangePaymentCode>
<PaymentAmount>-43.04</PaymentAmount>
<PaymentCoverageStartDate>2016-10-01</PaymentCoverageStartDate>
<PaymentCoverageEndDate>2016-10-31</PaymentCoverageEndDate>
</RemittanceDetail>
</RemittanceInformation>
<RemittanceInformation>
<EntityAssignedNumber>26</EntityAssignedNumber>
<IndividualRemittance>
<IndividualName>
<LastName>Johnson</LastName>
<FirstName>Steve</FirstName>
<ExchangeAssignedSubscriberID>0000442525</ExchangeAssignedSubscriberID>
</IndividualName>
<ExchangeAssignedQHPID>38408SC001000101</ExchangeAssignedQHPID>
<ExchangeAssignedPolicyID>26141334</ExchangeAssignedPolicyID>
<IssuerAssignedPolicyID>39147964</IssuerAssignedPolicyID>
<IssuerAssignedSubscriberID>101009913000</IssuerAssignedSubscriberID>
</IndividualRemittance>
<RemittanceDetail>
<ExchangePaymentCode>APTC</ExchangePaymentCode>
<PaymentAmount>556.00</PaymentAmount>
<PaymentCoverageStartDate>2016-10-01</PaymentCoverageStartDate>
<PaymentCoverageEndDate>2016-10-31</PaymentCoverageEndDate>
</RemittanceDetail>
<RemittanceDetail>
<ExchangePaymentCode>UF</ExchangePaymentCode>
<PaymentAmount>-30.50</PaymentAmount>
<PaymentCoverageStartDate>2016-10-01</PaymentCoverageStartDate>
<PaymentCoverageEndDate>2016-10-31</PaymentCoverageEndDate>
</RemittanceDetail>
</RemittanceInformation>
<RemittanceInformation>
<EntityAssignedNumber>27</EntityAssignedNumber>
<IndividualRemittance>
<IndividualName>
<LastName>Masterson</LastName>
<FirstName>Gene</FirstName>
<MiddleName>E</MiddleName>
<ExchangeAssignedSubscriberID>0032171620</ExchangeAssignedSubscriberID>
</IndividualName>
<ExchangeAssignedQHPID>384111C001000101</ExchangeAssignedQHPID>
<ExchangeAssignedPolicyID>26523035</ExchangeAssignedPolicyID>
<IssuerAssignedPolicyID>38976623</IssuerAssignedPolicyID>
<IssuerAssignedSubscriberID>101009869500</IssuerAssignedSubscriberID>
</IndividualRemittance>
<RemittanceDetail>
<ExchangePaymentCode>APTC</ExchangePaymentCode>
<PaymentAmount>448.00</PaymentAmount>
<PaymentCoverageStartDate>2016-10-01</PaymentCoverageStartDate>
<PaymentCoverageEndDate>2016-10-31</PaymentCoverageEndDate>
</RemittanceDetail>
<RemittanceDetail>
<ExchangePaymentCode>UF</ExchangePaymentCode>
<PaymentAmount>-30.50</PaymentAmount>
<PaymentCoverageStartDate>2016-10-01</PaymentCoverageStartDate>
<PaymentCoverageEndDate>2016-10-31</PaymentCoverageEndDate>
</RemittanceDetail>
</RemittanceInformation>
</root>
我在上述格式的 XML 文件中有大量数据。一个人用一个 "RemittanceInformation" 表示,但有一些重复。我想合并这些重复项并将所有重复项中的 "RemittanceDetail" 个实例添加到该人的第一个实例中。一个人由 "ExchangeAssignedPolicyID" 号码唯一标识。
在上面的示例中,应将 26 号的两个 RemittanceDetail 节点移至 25 号的 RemittanceInformation,因为他们都是同一个人,具有相同的 ExchangeAssignedPolicyID。所有以下 RemittanceInformation 节点都应递减以弥补缺失的数量。
我在 S/O 上看到过类似的代码,但经过很多小时和大量咖啡后我无法弄清楚。任何帮助将不胜感激。
如果您在 XSLT 2.0 中使用 for-each-group
(参见 https://www.w3.org/TR/xslt20/#grouping-examples 中的示例),那么您只需要
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="RemittanceInformation" group-by="IndividualRemittance/ExchangeAssignedPolicyID">
<xsl:copy>
<xsl:apply-templates select="EntityAssignedNumber, IndividualRemittance, current-group()/RemittanceDetail"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:transform>
在线 http://xsltransform.net/ejivdHd。
关于 EntityAssignedNumber
元素的适配,这里有一些改变来实现:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="RemittanceInformation" group-by="IndividualRemittance/ExchangeAssignedPolicyID">
<xsl:copy>
<xsl:variable name="pos" select="position()"/>
<xsl:apply-templates select="EntityAssignedNumber, IndividualRemittance, current-group()/RemittanceDetail">
<xsl:with-param name="pos" select="$pos"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="EntityAssignedNumber">
<xsl:param name="pos"/>
<xsl:copy>
<xsl:value-of select="/root/RemittanceInformation[1]/EntityAssignedNumber + $pos - 1"/>
</xsl:copy>
</xsl:template>
</xsl:transform>
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="Test1.xsl"?>
<root>
<RemittanceInformation>
<EntityAssignedNumber>25</EntityAssignedNumber>
<IndividualRemittance>
<IndividualName>
<LastName>Johnson</LastName>
<FirstName>Steve</FirstName>
<ExchangeAssignedSubscriberID>6650442525</ExchangeAssignedSubscriberID>
</IndividualName>
<ExchangeAssignedQHPID>38408SC221000101</ExchangeAssignedQHPID>
<ExchangeAssignedPolicyID>26141334</ExchangeAssignedPolicyID>
<IssuerAssignedPolicyID>39147964</IssuerAssignedPolicyID>
<IssuerAssignedSubscriberID>101009913000</IssuerAssignedSubscriberID>
</IndividualRemittance>
<RemittanceDetail>
<ExchangePaymentCode>APTC</ExchangePaymentCode>
<PaymentAmount>214.00</PaymentAmount>
<PaymentCoverageStartDate>2016-10-01</PaymentCoverageStartDate>
<PaymentCoverageEndDate>2016-10-31</PaymentCoverageEndDate>
</RemittanceDetail>
<RemittanceDetail>
<ExchangePaymentCode>UF</ExchangePaymentCode>
<PaymentAmount>-43.04</PaymentAmount>
<PaymentCoverageStartDate>2016-10-01</PaymentCoverageStartDate>
<PaymentCoverageEndDate>2016-10-31</PaymentCoverageEndDate>
</RemittanceDetail>
</RemittanceInformation>
<RemittanceInformation>
<EntityAssignedNumber>26</EntityAssignedNumber>
<IndividualRemittance>
<IndividualName>
<LastName>Johnson</LastName>
<FirstName>Steve</FirstName>
<ExchangeAssignedSubscriberID>0000442525</ExchangeAssignedSubscriberID>
</IndividualName>
<ExchangeAssignedQHPID>38408SC001000101</ExchangeAssignedQHPID>
<ExchangeAssignedPolicyID>26141334</ExchangeAssignedPolicyID>
<IssuerAssignedPolicyID>39147964</IssuerAssignedPolicyID>
<IssuerAssignedSubscriberID>101009913000</IssuerAssignedSubscriberID>
</IndividualRemittance>
<RemittanceDetail>
<ExchangePaymentCode>APTC</ExchangePaymentCode>
<PaymentAmount>556.00</PaymentAmount>
<PaymentCoverageStartDate>2016-10-01</PaymentCoverageStartDate>
<PaymentCoverageEndDate>2016-10-31</PaymentCoverageEndDate>
</RemittanceDetail>
<RemittanceDetail>
<ExchangePaymentCode>UF</ExchangePaymentCode>
<PaymentAmount>-30.50</PaymentAmount>
<PaymentCoverageStartDate>2016-10-01</PaymentCoverageStartDate>
<PaymentCoverageEndDate>2016-10-31</PaymentCoverageEndDate>
</RemittanceDetail>
</RemittanceInformation>
<RemittanceInformation>
<EntityAssignedNumber>27</EntityAssignedNumber>
<IndividualRemittance>
<IndividualName>
<LastName>Masterson</LastName>
<FirstName>Gene</FirstName>
<MiddleName>E</MiddleName>
<ExchangeAssignedSubscriberID>0032171620</ExchangeAssignedSubscriberID>
</IndividualName>
<ExchangeAssignedQHPID>384111C001000101</ExchangeAssignedQHPID>
<ExchangeAssignedPolicyID>26523035</ExchangeAssignedPolicyID>
<IssuerAssignedPolicyID>38976623</IssuerAssignedPolicyID>
<IssuerAssignedSubscriberID>101009869500</IssuerAssignedSubscriberID>
</IndividualRemittance>
<RemittanceDetail>
<ExchangePaymentCode>APTC</ExchangePaymentCode>
<PaymentAmount>448.00</PaymentAmount>
<PaymentCoverageStartDate>2016-10-01</PaymentCoverageStartDate>
<PaymentCoverageEndDate>2016-10-31</PaymentCoverageEndDate>
</RemittanceDetail>
<RemittanceDetail>
<ExchangePaymentCode>UF</ExchangePaymentCode>
<PaymentAmount>-30.50</PaymentAmount>
<PaymentCoverageStartDate>2016-10-01</PaymentCoverageStartDate>
<PaymentCoverageEndDate>2016-10-31</PaymentCoverageEndDate>
</RemittanceDetail>
</RemittanceInformation>
</root>
我在上述格式的 XML 文件中有大量数据。一个人用一个 "RemittanceInformation" 表示,但有一些重复。我想合并这些重复项并将所有重复项中的 "RemittanceDetail" 个实例添加到该人的第一个实例中。一个人由 "ExchangeAssignedPolicyID" 号码唯一标识。
在上面的示例中,应将 26 号的两个 RemittanceDetail 节点移至 25 号的 RemittanceInformation,因为他们都是同一个人,具有相同的 ExchangeAssignedPolicyID。所有以下 RemittanceInformation 节点都应递减以弥补缺失的数量。
我在 S/O 上看到过类似的代码,但经过很多小时和大量咖啡后我无法弄清楚。任何帮助将不胜感激。
如果您在 XSLT 2.0 中使用 for-each-group
(参见 https://www.w3.org/TR/xslt20/#grouping-examples 中的示例),那么您只需要
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="RemittanceInformation" group-by="IndividualRemittance/ExchangeAssignedPolicyID">
<xsl:copy>
<xsl:apply-templates select="EntityAssignedNumber, IndividualRemittance, current-group()/RemittanceDetail"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:transform>
在线 http://xsltransform.net/ejivdHd。
关于 EntityAssignedNumber
元素的适配,这里有一些改变来实现:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="RemittanceInformation" group-by="IndividualRemittance/ExchangeAssignedPolicyID">
<xsl:copy>
<xsl:variable name="pos" select="position()"/>
<xsl:apply-templates select="EntityAssignedNumber, IndividualRemittance, current-group()/RemittanceDetail">
<xsl:with-param name="pos" select="$pos"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="EntityAssignedNumber">
<xsl:param name="pos"/>
<xsl:copy>
<xsl:value-of select="/root/RemittanceInformation[1]/EntityAssignedNumber + $pos - 1"/>
</xsl:copy>
</xsl:template>
</xsl:transform>