使用Java将xSLT拆分为多个文件

时间:2016-04-06 11:10:12

标签: java xml xslt transform saxon

我有一个XML文件,需要根据Xpath变量上的匹配(Contains)进行拆分。

`<Apps>
    <App>
        <AppID>49O</AppID>
        <Type>MP Pay</Type>
    </App>
    <App>
        <AppID>715</AppID>
        <Type>DP Pay</Type>
    </App>
    <App>
        <AppID>716</AppID>
        <Type>MP Pay</Type>
    </App>
    <App>
        <AppID>725</AppID>
        <Type>CP Pay</Type>
    </App>
    <App>
        <AppID>728</AppID>
        <Type>MP Pay</Type>
    </App>
   <App>
        <AppID>728</AppID>
        <Type>CP Pay</Type>
    </App>
</Apps>`

因此分割xml的条件是 1.应用程序/应用程序/类型/文本() - &gt;包含'MP' 2.应用/应用/类型/文本() - &gt;包含'DP'

以下是预期产出:

  1. 包含Type为'MP'的所有App节点都应该在一个文件中 - &gt; MP.xml。

    <Apps> <App> <AppID>49O</AppID> <Type>MP Pay</Type> </App> <App> <AppID>716</AppID> <Type>MP Pay</Type> </App> <App> <AppID>728</AppID> <Type>MP Pay</Type> </App> </Apps>

  2. 包含类型为“DP”的所有App节点都应位于文件中 - &gt; DP.xml。

    <Apps> <App> <AppID>715</AppID> <Type>DP Pay</Type> </App> </Apps>

  3. 所有App节点无法匹配上述2个条件应该在文件中 - &gt; Mismatched.xml。

    <Apps> <App> <AppID>715</AppID> <Type>CP Pay</Type> </App> <App> <AppID>725</AppID> <Type>CP Pay</Type> </App> </Apps>

  4. Java代码

    public class Splitter {
    
        public static void transform(String sourcePath, String xsltPath,
                String resultDir) {
    
            TransformerFactory tFactory = TransformerFactory.newInstance();
            try {
                Transformer transformer = tFactory.newTransformer(new StreamSource(
                        new File(xsltPath)));
                transformer.transform(new StreamSource(new File(sourcePath)),
                        new StreamResult(new File(resultDir)));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
    
            // Set saxon as transformer.
            System.setProperty("javax.xml.transform.TransformerFactory",
                    "net.sf.saxon.TransformerFactoryImpl");
    
            String inputFilepath = "resources\\InputFile.xml";
            String transformXsltPath = "resources\\Transform.xslt";
            String outputDir = "D://Tmp//";
    
            transform(inputFilepath, transformXsltPath, outputDir);
            System.out.println("Completed");
        }
    
    }
    

2 个答案:

答案 0 :(得分:0)

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output indent="yes"/>

   <xsl:template match="Apps">
      <xsl:result-document href="MP.xml">
         <xsl:copy>
            <xsl:apply-templates select="App[contains(Type, 'MP')]"/>
         </xsl:copy>
      </xsl:result-document>
      <xsl:result-document href="DP.xml">
         <xsl:copy>
            <xsl:apply-templates select="App[contains(Type, 'DP')]"/>
         </xsl:copy>
      </xsl:result-document>
      <xsl:result-document href="Mismatched.xml">
         <xsl:copy>
            <xsl:apply-templates select="App[not(contains(Type, 'MP') or contains(Type, 'DP'))]"/>
         </xsl:copy>
      </xsl:result-document>
   </xsl:template>

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

答案 1 :(得分:0)

这是一种更基于规则的方法:

<xsl:template match="App[starts-with(Type, 'MP')]" mode="group">MP</xsl:template>

<xsl:template match="App[starts-with(Type, 'DP')]" mode="group">DP</xsl:template>

<xsl:template match="App" mode="group">Mismatched</xsl:template>

<xsl:function name="f:key" as="xs:string">
  <xsl:param name="e" as="element(App)"/>
  <xsl:apply-templates select="." mode="group"/>
</xsl:function>

<xsl:template match="Apps">
  <xsl:for-each-group select="App" group-by="f:key(.)">
      <xsl:result-document href="{current-grouping-key()}.xml">
         <Apps>
            <xsl:copy-of select="current-group()"/>
         </Apps>
      </xsl:result-document>
  </xsl:for-each-group>
</xsl:template>