6

XMLStreamReaderアプリケーションに必要なデータが w3c ドキュメントとして含まれていることを受け入れるコード ベースの既存のコードを再利用したいと考えています。

次の例は、最小限のテスト ケースです。

public static void main(String[] args) throws Exception {
    DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = builderFactory.newDocumentBuilder();

    Document doc = builder.newDocument();

    Element rootElement = doc.createElement("Groups");
    doc.appendChild(rootElement);
    Element group = doc.createElement("Group");
    group.setTextContent("Wibble");
    rootElement.appendChild(group);

    DOMSource source = new DOMSource(doc);

    XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(source);

    reader.nextTag();
    System.out.println("NextTag:" + reader.getName());
}

予想される出力は次のようになるはずですNextTag:Groupsが、代わりに次がスローされます。

Exception in thread "main" javax.xml.stream.XMLStreamException: java.net.MalformedURLException
    at com.sun.xml.stream.XMLReaderImpl.setInputSource(XMLReaderImpl.java:196)
    at com.sun.xml.stream.XMLReaderImpl.<init>(XMLReaderImpl.java:179)
    at com.sun.xml.stream.ZephyrParserFactory.createXMLStreamReader(ZephyrParserFactory.java:139)
    at Main.main(Main.java:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.net.MalformedURLException
    at java.net.URL.<init>(URL.java:601)
    at java.net.URL.<init>(URL.java:464)
    at java.net.URL.<init>(URL.java:413)
    at com.sun.xml.stream.XMLEntityManager.startEntity(XMLEntityManager.java:762)
    at com.sun.xml.stream.XMLEntityManager.startDocumentEntity(XMLEntityManager.java:697)
    at com.sun.xml.stream.XMLDocumentScannerImpl.setInputSource(XMLDocumentScannerImpl.java:300)
    at com.sun.xml.stream.XMLReaderImpl.setInputSource(XMLReaderImpl.java:193)
    ... 8 

現在、Java 6 update 22 を使用しています。

詳細情報: ZephyrParserFactory#jaxpSourcetoXMLInputSourceSystemIdのソースは、DOMSource の実際のコンテンツではなく、それをコピーすることによって Source オブジェクトが変換されることを示しているようです。

更新:上記の元のテスト ケースは、sjsxp 1.0.1 をプルする JAXB 2.2.1 ライブラリを実際に含むプロジェクト クラスパスを使用して実際に実行されました。クリーンなクラスパスで実行すると、次の結果が得られます。

Exception in thread "main" java.lang.UnsupportedOperationException: Cannot create XMLStreamReader or XMLEventReader from a javax.xml.transform.dom.DOMSource
    at com.sun.xml.internal.stream.XMLInputFactoryImpl.jaxpSourcetoXMLInputSource(XMLInputFactoryImpl.java:302)
    at com.sun.xml.internal.stream.XMLInputFactoryImpl.createXMLStreamReader(XMLInputFactoryImpl.java:145)

これは@Gary Roweの答えに適合します。

4

5 に答える 5

2

Woodstox は、WstxDOMWrappingReader クラスで必要なものを正確に提供します。https://fasterxml.github.io/woodstox/javadoc/5.0/com/ctc/wstx/dom/WstxDOMWrappingReader.htmlで Javadoc を参照してください。

小さな例:

  DOMSource domSource = new DOMSource(node);
  ReaderConfig config = ReaderConfig.createFullDefaults();
  XMLStreamReader reader = WstxDOMWrappingReader.createFrom(domSource, config);
于 2016-03-15T10:11:54.107 に答える
2

少し複雑ですが、XQJ API (Saxon など) をサポートする XQuery 実装では、クエリ "." への入力として DOM を指定し、結果を XMLStreamReader として取得できます。重い機械がたくさん使われていますが、完全に効率的でなければなりません。

Saxon では、次のようなものを使用して XQuery 側を短絡することもできます。

Document doc; // the DOM document
XMLStreamReader reader = new PullToStax(PullProvider.makePullProvider(new DocumentWrapper(doc));

しかし、XQJ のアプローチの方がクリーンだと思います。

于 2011-08-31T14:34:32.713 に答える
1

私の実用的な解決策は、を使用してドキュメントをbyte配列に出力し、それを使用ByteArrayOutputStreamしてフィードバックすることでした。ByteArrayInputStream

Transformer xformer = TransformerFactory.newInstance().newTransformer();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
StreamResult out = new StreamResult(outputStream);
xformer.transform(source, out);
reader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(outputStream.toByteArray()));

きれいではありませんが、機能します。

于 2011-09-01T07:54:13.670 に答える
1

aDOMSourceは a のインスタンスではないStreamSourceので、追い出されているようです。

于 2011-08-31T14:15:37.340 に答える