【问题标题】:Need help on splitting XML using XSLT based on groups在使用基于组的 XSLT 拆分 XML 方面需要帮助
【发布时间】:2017-06-29 07:40:03
【问题描述】:

我需要根据 XML 中不同值的数量将 XML 拆分为 x 个文件。

示例 源 XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <MT_RemittanceAdvice>
    <header>
      <companyName>Dept Store</companyName>
      <DocumentType>Remittance Advice</DocumentType>
      <postDate>06/01/2017 03:27:16</postDate>
      <payeeName>xxxxxxxxxxxx</payeeName>
      <checkDate>05/31/2017</checkDate>
      <checkNumber>6321713</checkNumber>
      <region/>
      <amount>13,570.80</amount>
    </header>
    <body>
       <article>
            <transCode/>
            <poNumber>2023090</poNumber>
            <docRef/>
            <site>MY SHOPPINGLANE CEBU, CORP</site>
            <grossAmount>55.80</grossAmount>
            <discount>-0.50</discount>
            <netAmount>-55.30</netAmount>
       </article>
       <article>
            <transCode/>
            <poNumber>210205</poNumber>
            <docRef/>
            <site>ACE HARDWARE PHILS., INC.</site>
            <grossAmount>55.80</grossAmount>
            <discount>-0.50</discount>
            <netAmount>-55.30</netAmount>
        </article>
        <article>
            <transCode/>
            <poNumber>20239479</poNumber>
            <docRef/>
            <site>ACE HARDWARE PHILS., INC.</site>
            <grossAmount>0.00</grossAmount>
            <discount>80.44</discount>
            <netAmount>8,928.62</netAmount>
            </article>
    </body>
    <footer>
           <totalAmount>0.00</totalAmount>
           <ewtAmount>0.00</ewtAmount>
           <arItcc>0.00</arItcc>
           <netPayable>13,570.80</netPayable>
           <importantRemarks><![CDATA[Please review your Details of Payment immediately. Discrepancy noted should be reported within 60 days from credit date. Any request for reconciliation beyond this period shall not be given priority.]]></importantRemarks>
    </footer>

所需结果:使用“站点”将单个 XML 拆分为 2 个 XML。 ACE 1 个,MY SHOPPING LANE 1 个。

第一个 XML

    <?xml version="1.0" encoding="UTF-8"?>
    <MT_RemittanceAdvice>
    <header>
      <companyName>Dept Store</companyName>
      <DocumentType>Remittance Advice</DocumentType>
      <postDate>06/01/2017 03:27:16</postDate>
      <payeeName>xxxxxxxxxxxx</payeeName>
      <checkDate>05/31/2017</checkDate>
      <checkNumber>6321713</checkNumber>
      <region/>
      <amount>13,570.80</amount>
    </header>
    <body>
       <article>
            <transCode/>
            <poNumber>2023090</poNumber>
            <docRef/>
            <site>MY SHOPPINGLANE CEBU, CORP</site>
            <grossAmount>55.80</grossAmount>
            <discount>-0.50</discount>
            <netAmount>-55.30</netAmount>
       </article>
    </body>
    <footer>
           <totalAmount>0.00</totalAmount>
           <ewtAmount>0.00</ewtAmount>
           <arItcc>0.00</arItcc>
           <netPayable>13,570.80</netPayable>
           <importantRemarks><![CDATA[Please review your Details of Payment immediately. Discrepancy noted should be reported within 60 days from credit date. Any request for reconciliation beyond this period shall not be given priority.]]></importantRemarks>

第二个 XML

    <?xml version="1.0" encoding="UTF-8"?>
    <MT_RemittanceAdvice>
    <header>
      <companyName>Dept Store</companyName>
      <DocumentType>Remittance Advice</DocumentType>
      <postDate>06/01/2017 03:27:16</postDate>
      <payeeName>xxxxxxxxxxxx</payeeName>
      <checkDate>05/31/2017</checkDate>
      <checkNumber>6321713</checkNumber>
      <region/>
      <amount>13,570.80</amount>
    </header>
    <body>
       <article>
            <transCode/>
            <poNumber>210205</poNumber>
            <docRef/>
            <site>ACE HARDWARE PHILS., INC.</site>
            <grossAmount>55.80</grossAmount>
            <discount>-0.50</discount>
            <netAmount>-55.30</netAmount>
        </article>
        <article>
            <transCode/>
            <poNumber>20239479</poNumber>
            <docRef/>
            <site>ACE HARDWARE PHILS., INC.</site>
            <grossAmount>0.00</grossAmount>
            <discount>80.44</discount>
            <netAmount>8,928.62</netAmount>
            </article>
    </body>
    <footer>
           <totalAmount>0.00</totalAmount>
           <ewtAmount>0.00</ewtAmount>
           <arItcc>0.00</arItcc>
           <netPayable>13,570.80</netPayable>
           <importantRemarks><![CDATA[Please review your Details of Payment immediately. Discrepancy noted should be reported within 60 days from credit date. Any request for reconciliation beyond this period shall not be given priority.]]></importantRemarks>
    </footer>

页眉和页脚都是从源 XML 文件中复制而来的。

以下是我为它创建 XSLT 的尝试:

          <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

<xsl:template match="MT_RemittanceAdvice/header">
    <header>
        <xsl:apply-templates/>
    </header>
</xsl:template>

<xsl:template match="/MT_RemittanceAdvice/body">

    <xsl:for-each-group select="MT_RemittanceAdvice/body/article" group-by="site">
    <body>
        <xsl:result-document method="xml" href="RA_{@ID}-output.xml">
                <xsl:copy-of select="current-group()"/>
        </xsl:result-document>
    </body>
    </xsl:for-each-group>

</xsl:template>

<xsl:template match="MT_RemittanceAdvice/footer">
    <footer>
    <xsl:apply-templates/>
    </footer>
</xsl:template>

【问题讨论】:

    标签: xml xslt-2.0 xslt-grouping


    【解决方案1】:

    我不确定您想从哪里获取文件名(您的输入中没有 @ID 属性),但假设您可以使用可以使用的文件索引

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="xs"
        version="2.0">
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="/">
            <xsl:for-each-group select="MT_RemittanceAdvice/body/article" group-by="site">
                    <xsl:result-document method="xml" href="RA_{position()}-output.xml">
                        <xsl:apply-templates select="/*"/>
                    </xsl:result-document>  
            </xsl:for-each-group>
        </xsl:template>
    
        <xsl:template match="MT_RemittanceAdvice/body/article">
            <xsl:if test=". intersect current-group()">
                <xsl:next-match/>
            </xsl:if>
        </xsl:template>
    
    </xsl:stylesheet>
    

    当然也可以根据需要简单地调整 xsl:result-document method="xml" href="RA_{position()}-output.xml"

    【讨论】:

    猜你喜欢
    • 2011-01-11
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-24
    相关资源
    最近更新 更多