彼ら。
それがバグなのか、それとも私自身の教育不足なのかを理解するためにかなりの時間を費やしました。基本的に、私は特定の要素に反応し、JavaStAXAPIを使用してTransformerでその内容を読み取ろうとしています。
XMLがきれいにフォーマットされているか、要素間にスペースがある場合は、すべてが機能します。ただし、要素間に空白文字がないXMLを検出するとすぐに、ひどく壊れます。
問題を説明するためのコードとその出力があります。
3つのサンプルXMLがあり、最初の2つは2つの異なるブレークシナリオを示し、最後の1つは適切な処理を示しています。
スペースのない最初のシナリオでは、いくつかの要素をスキップします。以下の例では、1つの「ノード」要素を除くすべてをスキップします。実際のシナリオでは、代わりに他のすべてのノードをスキップします。おそらく、ノードのコンテンツが豊富なためです。
2番目のシナリオでは、ノード要素間にのみスペースを追加しました。ご覧のとおり、ドキュメントの終わりを適切に処理できません。
最後のシナリオでは、最後のノードとルート要素を閉じる間にスペースを追加しました。処理は希望どおりに行われました。
私の実際のシナリオでは、区切り文字のない単一行のXMLを期待しているので、シナリオ1が正しく機能する必要があります。また、要素間にスペースを追加するなど、XMLに有効な変更を加えても、処理が中断されないことを知って幸せです。シナリオ2のように。
助けてください!!!
シングルクラスアプリケーションテストの完全なコード。StAXTest:
package test;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
public class StAXTest {
private final static String XML1 = "<root><node></node><node></node></root>";
private final static String XML2 = "<root><node></node> <node></node></root>";
private final static String XML3 = "<root><node></node> <node></node> </root>";
public static void main(String[] args) throws Exception {
processXML(XML1);
processXML(XML2);
processXML(XML3);
}
private static void processXML(String xml) {
try {
System.out.println("XML Input:\n" + xml + "\nProcessing:");
XMLInputFactory xif = XMLInputFactory.newInstance();
XMLStreamReader reader = xif.createXMLStreamReader(new StringReader(xml));
TransformerFactory tf = TransformerFactory.newInstance();
int nodeCount = 0;
while (reader.nextTag() == XMLStreamConstants.START_ELEMENT) {
String localName = reader.getLocalName();
if (localName.equals("node")) {
Transformer t = tf.newTransformer();
StringWriter st = new StringWriter();
t.transform(new StAXSource(reader), new StreamResult(st));
String xmlNode = st.toString();
System.out.println(nodeCount + ": " + xmlNode);
nodeCount++;
}
}
} catch (Throwable t) {
t.printStackTrace(System.out);
}
System.out.println("------------------------------------------------");
}
}
3つのシナリオすべてを含むアプリケーション出力。最初のシナリオでは、変換されたXML部分に2つではなく1つのノードが含まれていることに注意してください。したがって、2番目のノードは完全に「変換で失われます」。
XML Input:
<root><node></node><node></node></root>
Processing:
0: <?xml version="1.0" encoding="UTF-8"?><node/>
------------------------------------------------
XML Input:
<root><node></node> <node></node></root>
Processing:
0: <?xml version="1.0" encoding="UTF-8"?><node/>
1: <?xml version="1.0" encoding="UTF-8"?><node/>
javax.xml.stream.XMLStreamException: ParseError at [row,col]:[-1,-1]
Message: found: END_DOCUMENT, expected START_ELEMENT or END_ELEMENT
at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.nextTag(XMLStreamReaderImpl.java:1247)
at com.newedge.test.StAXTest.processXML(StAXTest.java:35)
at com.newedge.test.StAXTest.main(StAXTest.java:21)
------------------------------------------------
XML Input:
<root><node></node> <node></node> </root>
Processing:
0: <?xml version="1.0" encoding="UTF-8"?><node/>
1: <?xml version="1.0" encoding="UTF-8"?><node/>
------------------------------------------------