XMLStreamSubReader改

無いなら作ろう 無いなら作ろう(その2)を読んで

<?xml version="1.0" encoding="Windows-31J" ?> 
<a> 
  <b> 
    <c> 
      <b> </b> 
    </c> 
  ,</b> 
</a>

に対応するようXMLStreamSubReaderを改造してみた。

import javax.xml.stream.XMLStreamConstants; 
import javax.xml.stream.XMLStreamException; 
import javax.xml.stream.XMLStreamReader; 
import javax.xml.stream.util.StreamReaderDelegate; 
 
public class XMLStreamSubReader extends StreamReaderDelegate { 
    protected String targetNode; 
    protected boolean breakTargetNode; 

    protected int countTargetNode; 
 
    public XMLStreamSubReader(XMLStreamReader delegateReader) { 
        super(delegateReader); 
        this.targetNode = delegateReader.getLocalName(); 
        this.breakTargetNode = false; 

    } 
 
    @Override 
    public boolean hasNext() throws XMLStreamException { 
        if ( this.breakTargetNode) { 
            return false; 

        } else { 
            return this.getParent().hasNext(); 
        } 
    } 
 
    @Override 
    public int next() throws XMLStreamException { 

 
        switch (this.getParent().getEventType()) { 
            case XMLStreamConstants.START_ELEMENT: 
                if ( this.getParent().getLocalName().equals(this.targetNode)) { 
                    countTargetNode++; 

                    this.breakTargetNode = false; 
                } 
                break; 
            case XMLStreamConstants.END_ELEMENT: 
                if ( this.getParent().getLocalName().equals(this.targetNode)) { 

                    countTargetNode--; 
                    this.breakTargetNode = (countTargetNode == 0); 
                } 
                break; 
            case XMLStreamConstants.END_DOCUMENT: 
                this.breakTargetNode = true; 

                break; 
        } 
 
        return this.getParent().next(); 
    } 
} 

テストコードはこんな感じ。

import javax.xml.stream.XMLStreamReader; 
import javax.xml.stream.XMLInputFactory; 
import java.io.BufferedInputStream; 
import java.io.FileInputStream; 
 
 
public class Tester { 
 
    private static final String fileName = "test.xml"; 
 
    public static void main(String[] args) throws Exception{ 

        // 入力ファクトリを取得する 
        XMLInputFactory xmlif = XMLInputFactory.newInstance(); 
 
        BufferedInputStream stream = new BufferedInputStream(new FileInputStream(fileName)); 

        XMLStreamReader reader = xmlif.createXMLStreamReader(stream); 
 
        for(;reader.hasNext();reader.next()){ 
 
            if(reader.isStartElement()){ 
                if("b".equals(reader.getLocalName())){ 
                    XMLStreamReader subReader = new XMLStreamSubReader(reader); 

                    for (; subReader.hasNext(); subReader.next())  { 
                        //カレントノードのサブツリーのみを処理 
                        System.out.println( subReader.getLocalName()); 
                    } 
                } 
            } 
        } 
    } 
} 

ちなみに

<?xml version="1.0" encoding="Windows-31J" ?> 
<a> 
  <b> 
    <c> 
      <b> </b><b/> 
    </c> 
  </b> 
</a>

でも大丈夫。