【问题标题】:How do I merge duplicate nodes, using children in the comparison?如何在比较中使用子节点合并重复节点?
【发布时间】:2016-11-16 07:02:37
【问题描述】:

<?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 上看到过类似的代码,但是经过了很多小时和喝了很多咖啡后,我还是搞不明白。任何帮助将不胜感激。

【问题讨论】:

  • &lt;xsl:for-each-group select="RemittanceInformation" group-by="IndividualRemittance/ExchangeAssignedPolicyID"&gt; 是假设 XSLT 2.0 的开始。在w3.org/TR/xslt20/#grouping-examples 中了解如何使用 XSLT 2.0 进行分组。

标签: xml xslt xslt-2.0


【解决方案1】:

如果您在 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>

在线http://xsltransform.net/ejivdHd/1

【讨论】:

  • 我实际上已经编写了完全相同的代码,改编了另一个问题的答案(尽管我使用了样式表而不是转换),但无论哪种方式我都在胡言乱语,好像它完全不起作用:@987654324 @
  • 我也在使用 Saxon9he 和以下命令: java -jar saxon9he.jar -xsl:Test1.xsl -s:originalxml.xml -o:TestOutput.html 而且,这不会动数字下降,我剩下 25 和 27。
  • 回想起来,这似乎是一个完全不同的问题。如在线转换工具所示,您的答案似乎很完美。谢谢:D
  • 样式表创建的是 XML 输出,而不是 HTML,因此尝试在浏览器中查看它似乎不是检查它是否在工作的有意义的方式。我认为第一个样本不会产生乱码,它会根据需要进行分组。我为数字适配添加了改进。
  • 您完全正确,亲爱的先生!非常感谢,这太棒了。 :)
猜你喜欢
  • 1970-01-01
  • 2018-07-07
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 1970-01-01
  • 2015-02-28
  • 2017-01-13
  • 1970-01-01
相关资源
最近更新 更多