2016-04-06 12 views
0

XMLファイルがありますが、Xpath変数の一致(Contains)に基づいて分割する必要があります。Javaを使用して複数のファイルにXSLTを使用してxmlを分割

`<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.アプリ/アプリケーション/タイプ/テキストですので() - > 'MP' 2.アプリ/アプリケーション/タイプ/テキストを(入って) - > 'DP' を含みます以下は

期待される出力です:

  1. 'MP' とタイプを含むすべてのアプリケーションノードがファイルにする必要があります - > MP.xml。 > DP.xml - 'DP' とタイプを含む

    <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. すべてのアプリケーションノードがファイルにする必要があります。 > Mismatched.xml -

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

  3. すべてのAppは、上記2つの条件は、ファイルにする必要が一致するように失敗したノード。

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

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"); 
    } 

} 
+0

は、あなたが同様にあなたのJavaコードを投稿することができますか? Saxon、プレーンJava(xslt 2.0)を使用していますか? ありがとう、 Stephan –

+0

はい、Saxonを使用しています。私の質問自体にJavaコードを追加 –

答えて

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> 
+0

ありがとう。完璧に動作します! –

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> 
関連する問題