2017-06-14 16 views
0

saxパーサーを使用して、xml要素を(xmlから)特定の要素の下にある文字列として必要とします。SAXパーサーを使用すると、(特定の要素の下にある)すべてのxml要素が文字列として必要です

サンプルXML:

<root> 
    <meta> 
    <elememtA>xx</elememtA> 
    </meta> 
<payload> 
    <parent> 
     <child1>a</child1> 
    </parent> 
    <parent> 
     <child1>b</child1> 
    </parent> 
    </payload> 
</root> 

SAXパーサーの実装:例えば

public class UserHandler extends DefaultHandler { 
    @Override 
    public void startElement(String uri, 
    String localName, String qName, Attributes attributes) 
    throws SAXException { 
    if (qName.equalsIgnoreCase("payload")) { 
    //need all elements inside payload as string 
} 

私は休閑出力が必要です。

<parent><child1>a</child1></parent><parent><child2>b</child2></parent> 
+0

HIで、あなたが意味だと思います: B jeorfevre

+0

やあ、私はあなたを得るdidnt – pradeep

+0

は投稿を編集したばかりで、2番目の引数は b jeorfevre

答えて

1

は、コードを働いています。 結果は出力の最後に表示されます。楽しい。

JUnitの中に出力

2017-06-14 09:43:49 DEBUG SaxTest:94 - start document 
2017-06-14 09:43:49 DEBUG SaxTest:107 - START - - parent 
2017-06-14 09:43:49 DEBUG SaxTest:107 - START - - child1 
2017-06-14 09:43:49 DEBUG SaxTest:33 - STRING : a 
2017-06-14 09:43:49 DEBUG SaxTest:52 - END - - child1 
2017-06-14 09:43:49 DEBUG SaxTest:52 - END - - parent 
2017-06-14 09:43:49 DEBUG SaxTest:107 - START - - parent 
2017-06-14 09:43:49 DEBUG SaxTest:107 - START - - child1 
2017-06-14 09:43:49 DEBUG SaxTest:33 - STRING : b 
2017-06-14 09:43:49 DEBUG SaxTest:52 - END - - child1 
2017-06-14 09:43:49 DEBUG SaxTest:52 - END - - parent 
2017-06-14 09:43:49 DEBUG SaxTest:41 - end document 
2017-06-14 09:43:49 INFO SaxTest:148 - RESULT 
<parent><child1>a</child1></parent><parent><child1>b</child1></parent> 

コード - ワーキングテスト

package com.rizze.beans.labs.sof; 

import java.io.IOException; 
import java.io.StringReader; 

import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.parsers.SAXParserFactory; 

import org.junit.Test; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.xml.sax.Attributes; 
import org.xml.sax.ContentHandler; 
import org.xml.sax.InputSource; 
import org.xml.sax.Locator; 
import org.xml.sax.SAXException; 
import org.xml.sax.XMLReader; 

public class SaxTest { 

    public static Logger logger = LoggerFactory.getLogger(SaxTest.class); 


    public class SaxProcess implements ContentHandler { 

     private boolean start= false; 
     private static final String START_ITEM = "payload"; 
     private String result = ""; 

     @Override 
     public void characters(char[] ch, int begin, int length) throws SAXException { 
      if(start == true){ 
       logger.debug("STRING : "+new String(ch).substring(begin,begin+length)); 

       result+=new String(new String(ch).substring(begin,begin+length)); 
      } 
     } 

     @Override 
     public void endDocument() throws SAXException { 
         logger.debug("end document"); 
     } 

     @Override 
     public void endElement(String uri, String localName, String name) throws SAXException { 

      if(name!=null && name.compareToIgnoreCase(START_ITEM)==0){ 
       start = false; 
      } 
      else{ 
       if(start == true){ 
        logger.debug("END - "+ localName + " - " + name); 
        result+="</"+name+">"; 
       } 
      } 


     } 

     @Override 
     public void endPrefixMapping(String prefix) throws SAXException { 



     } 

     @Override 
     public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { 

     } 

     @Override 
     public void processingInstruction(String target, String data) throws SAXException { 


     } 

     @Override 
     public void setDocumentLocator(Locator locator) { 

     } 

     @Override 
     public void skippedEntity(String name) throws SAXException { 


     } 

     @Override 
     public void startDocument() throws SAXException { 
      start=false; 
      result = ""; 

      logger.debug("start document"); 
     } 

     @Override 
     public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException { 

      if(name!=null && name.compareToIgnoreCase(START_ITEM)==0){ 
       start = true; 
      } 
      else{ 

       if(start == true){ 
        //if already started ... go on 
        logger.debug("START - "+ localName + " - " + name); 
        result+="<"+name+">"; 
       } 
      } 


     } 

     @Override 
     public void startPrefixMapping(String prefix, String uri) throws SAXException { 


     } 

     /** 
     * return resulting string 
     * @return 
     */ 
     public String getResult(){ 
      return result; 
     } 

    } 





    @Test 
    public void test() { 


     String xml = "<root><meta><elememtA>xx</elememtA></meta><payload><parent><child1>a</child1></parent><parent><child1>b</child1></parent></payload></root>"; 
     InputSource in = new InputSource(new StringReader(xml)); 


      try { 
       XMLReader reader= SAXParserFactory.newInstance().newSAXParser().getXMLReader(); 
       SaxProcess p=new SaxProcess(); 
       reader.setContentHandler(p); 
       reader.parse(in); 
       logger.info("RESULT \n"+p.getResult()); 
      } catch (ParserConfigurationException | SAXException | IOException e) { 
       e.printStackTrace(); 
      } 

    } 

} 
+0

すごいコード! – SomeDude

+0

@svasa =>質問はSAXでContentHandlerを使用する方法でした。このコードは質問に応答し、1つのファイルでも動作します。ロギング/インポートを実行すると、コードサイズが50%減少します。 – jeorfevre

0

をあなたが必要と思われます出力i n xml形式、つまりxml形式でparentノードが必要です。 SAXParserまたはXPathエンジンは、ノードとノードの名前で動作します。あなたは非常に面倒でメンテナンスが難しいかもしれないxmlとして望ましい出力を返すための特別なコードを書く必要があります。

簡単に目的の出力xmlを得る1つの方法は、XSLTを使用することです。

は、XSLTを使用することを検討してください:ファイル内

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" omit-xml-declaration="yes"/> 
<xsl:template match="/"> 
    <xsl:copy-of select="//payload/parent"/> 
</xsl:template> 
</xsl:stylesheet> 

場所これはparentxslt.xmlと呼ばれ、その後、あなたはJavaコードの下に使用することができ、parent.xmlであなたの入力XMLを置く:ここ

try 
{ 
    File stylesheet = new File("parentxslt.xml"); 
    Transformer transformer = TransformerFactory.newInstance().newTransformer(new StreamSource(stylesheet)); 
    StreamSource xmlSource = new StreamSource(new File("parent.xml")); 
    StringWriter sw = new StringWriter(); 
    transformer.transform(xmlSource, new StreamResult(sw)); 

    System.out.println(sw.toString().replaceAll("\\\r\\n\\s*", "")); 

} 
catch (Exception ex) 
{ 
    ex.printStackTrace(); 
} 
+0

DOMを変換するだけで作成しないでください。トランスフォーマーには、StreamSourceまたはSAXSourceを提供する方がはるかに優れています。 –

+0

@MichaelKayコメントありがとう! 'StreamSource'を使用するようにコードを更新しました – SomeDude

+0

また、' 'に減らしてみませんか? –

関連する問題