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>
でも大丈夫。