2016-05-12 5 views
0

、Report.xmlをXMLファイルを考えてみましょう:分割より大きなサイズのXMLファイルをJavaを使用して(親の属性と兄弟を保持)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <Report FileName="abc.bin" reportDate="05/12/2016 02:44:22 AM"> 
     <Statistics> 
     <child value="abc"> 
     <subchild>...</subchild> 
     </child> 
     <child value="xyz"> 
     <subchild>...</subchild> 
     </child> 
     </Statistics> 
     <Properties> 
     <child1>...</child1> 
     <child2>...</child2> 
     . 
     . 
     . 
     <childn>...</childn> 
     </Properties> 
     <OverallStatistics> 
     <child1>...</child1> 
     <child2>...</child2> 
     . 
     . 
     . 
     <childn>...</child1> 
     </OverallStatistics> 
    </Report> 

私はちょうどとして上記のXMLファイルを分割したい:

ReportSplit1 .xmlの

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Report FileName="abc.bin" reportDate="05/12/2016 02:44:22 AM"> 
    <Statistics> 
     <child value="abc"> 
     <subchild>...</subchild> 
     </child> 
    </Statistics> 
    <Properties> 
     <child1>...</child1> 
     <child2>...</child2> 
     . 
     . 
     . 
     <childn>...</childn> 
    </Properties> 
    <OverallStatistics> 
     <child1>...</child1> 
     <child2>...</child2> 
     . 
     . 
     . 
     <childn>...</child1> 
    </OverallStatistics> 
</Report> 

ReportSplit2.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Report FileName="abc.bin" reportDate="05/12/2016 02:44:22 AM"> 
    <Statistics> 
     <child value="xyz"> 
     <subchild>...</subchild> 
     </child> 
    </Statistics> 
    <Properties> 
     <child1>...</child1> 
     <child2>...</child2> 
     . 
     . 
     . 
     <childn>...</childn> 
    </Properties> 
    <OverallStatistics> 
     <child1>...</child1> 
     <child2>...</child2> 
     . 
     . 
     . 
     <childn>...</child1> 
    </OverallStatistics> 
</Report> 

、すなわち、親ノードの属性を保持し、兄弟ノードを保持する。分割は、統計ノードの子に対してのみ行う必要があります。

package xmlsplitting; 
import java.io.*; 
import java.util.ArrayList; 
import java.util.List; 
import javax.xml.parsers.*; 
import org.w3c.dom.*; 
import org.xml.sax.*; 
import javax.xml.transform.*; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.xpath.*; 
public class XmlSplit 
{ 
    static public void main(String[] arg) throws Exception 
    { 
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder builder = factory.newDocumentBuilder(); 
     Document doc = builder.parse("D:\\Analyzer\\FileSplit\\Report.xml"); 
     TransformerFactory tranFactory = TransformerFactory.newInstance(); 
     Transformer aTransformer = tranFactory.newTransformer(); 
     XPath xpath = XPathFactory.newInstance().newXPath(); 
     NodeList list = (NodeList)xpath.evaluate("//Report/Statistics/child", doc, XPathConstants.NODESET); 
     for (int i=1; i<list.getLength(); i++) 
     { 
      Node element = list.item(i).cloneNode(true); 
      if(element.hasChildNodes()) 
      { 
        Source src = new DOMSource(element); 
        FileOutputStream fs = new FileOutputStream("D:\\Analyzer\\FileSplit\\ReportSplit"+ i + ".xml"); 
        Result dest = new StreamResult(fs); 
        aTransformer.transform(src, dest); 
        fs.close(); 
      } 
     } 
    } 
} 

達成XMLファイルの分割のようにスニペットを変更することにより、linkで与えられた回避策を追っ:

ReportSplit1.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <child value="abc"> 
     <subchild>...</subchild> 
    </child> 

ReportSplit2.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <child value="xyz"> 
     <subchild>...</subchild> 
    </child> 

誰でも希望のXMLファイルを分割するための回避策を提供できますか?

答えて

0

文書全体の変換が必要なときに、XPathの代わりにXML文書を変換するための宣言型の特別目的プログラミング言語XSLTを使用することを検討してください。あなたの目的のために値のループ上に、埋め込まれた、動的なXSLTの実行を出力することができ、複数のXMLファイル:

XSLTスクリプト(以下、埋め込み、例がここで繰り返し使用して交換された「ABC」を使用しています)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output version="1.0" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*"/> 

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

    <xsl:template match="child[not(@value='abc')]"/> 

</xsl:transform> 

のJavaスクリプト

import javax.xml.parsers.*; 
import javax.xml.transform.*; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.transform.stream.StreamSource; 
import javax.xml.transform.OutputKeys; 

import java.io.*; 
import java.net.URISyntaxException; 

import org.w3c.dom.Document; 
import org.xml.sax.SAXException; 
public class XmlSplit { 
    public static void main(String[] args) throws IOException, URISyntaxException, 
                SAXException, ParserConfigurationException, 
                TransformerException { 

     // Load XML Source 
     String inputXML = "/path/to/XMLSource.xml"; 

     // Declare XML Values Array 
     String[] xmlVals = {"abc", "xyz"}; 

     // Iterate through Values running dynamic, embedded XSLT 
     for (String s: xmlVals) { 
      String outputXML = "/path/to/output_" + s + ".xml"; 

      String xslStr = String.join("\n", 
       "<xsl:transform xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">", 
       "<xsl:output version=\"1.0\" encoding=\"UTF-8\" indent=\"yes\" />", 
       "<xsl:strip-space elements=\"*\"/>", 
       "<xsl:template match=\"@*|node()\">", 
       "<xsl:copy>", 
       "<xsl:apply-templates select=\"@*|node()\"/>", 
       "</xsl:copy>", 
       "</xsl:template>", 
       "<xsl:template match=\"child[not(@value='"+ s +"')]\"/>", 
       "</xsl:transform>"); 

      Source xslt = new StreamSource(new StringReader(xslStr));    
      DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();    
      DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); 
      Document doc = docBuilder.parse (new File(inputXML)); 

      // XSLT Transformation with pretty print 
      TransformerFactory prettyPrint = TransformerFactory.newInstance(); 
      Transformer transformer = prettyPrint.newTransformer(xslt); 

      transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); 
      transformer.setOutputProperty(OutputKeys.STANDALONE, "yes"); 
      transformer.setOutputProperty(OutputKeys.METHOD, "xml"); 
      transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
      transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 
      transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");       

      // Output Result to File 
      DOMSource source = new DOMSource(doc); 
      StreamResult result = new StreamResult(new File(outputXML));   
      transformer.transform(source, result); 
     } 

    } 
} 
0

あなたのxpath評価は、あなたが子供とそれ以下を探すことを表しています。 のプロパティのように、他のフィールドにも別の表現を追加する必要があります。

関連する問題