首页 > 解决方案 > 使用带有嵌套节点的 XSLT 转换 XML

问题描述

我正在尝试使用 XSLT 转换以下 XML

输入 XML

<reply>
    <lst>
        <str name="field">shipper-name</str>
        <str name="value">USPS</str>
        <int name="count">94</int>
        <arr name="pivot">
            <lst>
                <str name="field">original-count</str>
                <int name="value">1</int>
                <int name="count">94</int>
                <arr name="pivot">
                    <lst>
                        <str name="field">user-count</str>
                        <int name="value">1</int>
                        <int name="count">66</int>
                    </lst>
                    <lst>
                        <str name="field">user-count</str>
                        <int name="value">0</int>
                        <int name="count">15</int>
                    </lst>
                    <lst>
                        <str name="field">user-count</str>
                        <int name="value">2</int>
                        <int name="count">13</int>
                    </lst>
                </arr>
            </lst>
        </arr>
    </lst>
    <lst>
        <str name="field">shipper-name</str>
        <str name="value">FEDEX</str>
        <int name="count">207</int>
        <arr name="pivot">
            <lst>
                <str name="field">original-count</str>
                <int name="value">1</int>
                <int name="count">207</int>
                <arr name="pivot">
                    <lst>
                        <str name="field">user-count</str>
                        <int name="value">0</int>
                        <int name="count">155</int>
                    </lst>
                    <lst>
                        <str name="field">user-count</str>
                        <int name="value">1</int>
                        <int name="count">52</int>
                    </lst>
                </arr>
            </lst>
        </arr>
    </lst>
    <lst>
        <str name="field">shipper-name</str>
        <str name="value">DHL</str>
        <int name="count">3</int>
        <arr name="pivot">
            <lst>
                <str name="field">original-count</str>
                <int name="value">78</int>
                <int name="count">1</int>
                <arr name="pivot">
                    <lst>
                        <str name="field">user-count</str>
                        <int name="value">78</int>
                        <int name="count">1</int>
                    </lst>
                </arr>
            </lst>
            <lst>
                <str name="field">original-count</str>
                <int name="value">87</int>
                <int name="count">1</int>
                <arr name="pivot">
                    <lst>
                        <str name="field">user-count</str>
                        <int name="value">1</int>
                        <int name="count">1</int>
                    </lst>
                </arr>
            </lst>
            <lst>
                <str name="field">original-count</str>
                <int name="value">90</int>
                <int name="count">1</int>
                <arr name="pivot">
                    <lst>
                        <str name="field">user-count</str>
                        <int name="value">0</int>
                        <int name="count">1</int>
                    </lst>
                </arr>
            </lst>
        </arr>
    </lst>
    <lst>
        <lst>
            <str name="field">shipper-name</str>
            <str name="value">UPS</str>
            <int name="count">186</int>
            <arr name="pivot">
                <lst>
                    <str name="field">original-count</str>
                    <int name="value">1</int>
                    <int name="count">186</int>
                    <arr name="pivot">
                        <lst>
                            <str name="field">user-count</str>
                            <int name="value">1</int>
                            <int name="count">98</int>
                        </lst>
                        <lst>
                            <str name="field">user-count</str>
                            <int name="value">0</int>
                            <int name="count">78</int>
                        </lst>
                        <lst>
                            <str name="field">user-count</str>
                            <int name="value">30284</int>
                            <int name="count">1</int>
                        </lst>
                        <lst>
                            <str name="field">user-count</str>
                            <int name="value">30309</int>
                            <int name="count">1</int>
                        </lst>
                        <lst>
                            <str name="field">user-count</str>
                            <int name="value">30327</int>
                            <int name="count">1</int>
                        </lst>
                        <lst>
                            <str name="field">user-count</str>
                            <int name="value">30375</int>
                            <int name="count">1</int>
                        </lst>
                        <lst>
                            <str name="field">user-count</str>
                            <int name="value">30580</int>
                            <int name="count">1</int>
                        </lst>
                        <lst>
                            <str name="field">user-count</str>
                            <int name="value">30606</int>
                            <int name="count">1</int>
                        </lst>
                        <lst>
                            <str name="field">user-count</str>
                            <int name="value">30607</int>
                            <int name="count">1</int>
                        </lst>
                        <lst>
                            <str name="field">user-count</str>
                            <int name="value">30615</int>
                            <int name="count">1</int>
                        </lst>
                        <lst>
                            <str name="field">user-count</str>
                            <int name="value">30623</int>
                            <int name="count">1</int>
                        </lst>
                        <lst>
                            <str name="field">user-count</str>
                            <int name="value">30690</int>
                            <int name="count">1</int>
                        </lst>
                    </arr>
                </lst>
            </arr>
        </lst>
    </lst>
</reply>

我们希望通过比较原始计数和用户计数来找到不匹配计数。如果用户计数大于 0 并且与原始计数不同,我们会认为不匹配。

``` 
 <lst>
      <str name="field">name</str>
      <str name="value">USPS</str>
      <int name="count">94</int>
      <arr name="pivot">
        <lst>
          <str name="field">original-count</str>
          <int name="value">1</int>
          <int name="count">94</int>
          <arr name="pivot">
            <lst>
              <str name="field">user-count</str>
              <int name="value">1</int>
              <int name="count">66</int>
            </lst>
            <lst>
              <str name="field">user-count</str>
              <int name="value">0</int>
              <int name="count">15</int>
            </lst>
            <lst>
              <str name="field">user-count</str>
              <int name="value">2</int>
              <int name="count">13</int>
            </lst>
          </arr>
        </lst>
      </arr>
    </lst>      

    ```
    In the above there were total 94 shipments.
    Original counts with value 1 are 94.
    There are 66 user counts same as Original with value 1.
    there are 15 user counts with value 0.
    mismatched user counts are 13 with value 2 which is different from 1.
    so mismatched counts are 13.
<reply>
    <mismatch-list>
        <mismatch>
            <shipper-name>USPS</shipper-name>
            <shipment-count>94</shipment-count>
            <mismatch-count>13</mismatch-count>
        </mismatch>
        <mismatch>
            <shipper-name>FEDEX</shipper-name>
            <shipment-count>207</shipment-count>
            <mismatch-count>0</mismatch-count>
        </mismatch>
        <mismatch>
            <shipper-name>DHL</shipper-name>
            <shipment-count>3</shipment-count>
            <mismatch-count>13</mismatch-count>
        </mismatch>
        <mismatch>
            <shipper-name>UPS</shipper-name>
            <shipment-count>186</shipment-count>
            <mismatch-count>10</mismatch-count>
        </mismatch>
    </mismatch-list>
</reply>

我们希望通过比较原始计数和用户计数来找到不匹配计数。如果用户计数大于 0 并且与原始计数不同,我们会认为不匹配。

我尝试了以下但无法实现..

<xsl:template match="reply">
    <mismatch-list>
        <xsl:for-each select="lst">  
                <mismatch>
                    <shipper-name>
                        <xsl:value-of select="str[@name='value']"/>
                    </shipper-name>
                    <shipment-count>
                        <xsl:value-of select="int[@name='count']"/>
                    </shipment-count>
                    <mismatch-count>
                        <xsl:for-each select="arr[@name='pivot']/lst">
                            <xsl:variable name="origin_value_var">
                                <xsl:value-of select="int[@name='value']"/>
                            </xsl:variable>
                            <xsl:variable name="origin_count_var">
                                <xsl:value-of select="int[@name='count']"/>
                            </xsl:variable>
                            <xsl:for-each select="arr[@name='pivot']/lst/int[@name='value']">
                                <xsl:if test="current() > 0">
                                    <xsl:variable name="user_count_var">
                                        <xsl:value-of select="current()"/>
                                    </xsl:variable>
                                    <xsl:if
                                        test="(number($origin_value_var) - number(user_count_var) > 0 ) or (number(user_count_var) - number($origin_value_var) > 0)">
                                        <xsl:value-of
                                            select="count((number($origin_value_var) - number(user_count_var) > 0 ) or (number(user_count_var) - number($origin_value_var) > 0))"
                                        />
                                    </xsl:if>
                                </xsl:if>
                            </xsl:for-each>
                        </xsl:for-each>
                    </mismatch-count>
                </mismatch>
        </xsl:for-each>
    </mismatch-list>
</xsl:template>

标签: xslt

解决方案


推荐阅读