在使用基于组的 XSLT 拆分 XML 方面需要帮助
Need help on splitting XML using XSLT based on groups
我需要根据 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>
所需结果:使用 "site" 将单个 XML 拆分为 2 个 XML。 1 个用于 ACE,1 个用于 MY SHOPPING LANE。
第一个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>
我不确定你想从哪里获取文件名(你的输入中没有 @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"
。
我需要根据 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>
所需结果:使用 "site" 将单个 XML 拆分为 2 个 XML。 1 个用于 ACE,1 个用于 MY SHOPPING LANE。
第一个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>
我不确定你想从哪里获取文件名(你的输入中没有 @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"
。