java builder.parse((new StringReader(xml)) 返回 DeferredDocumentImpl

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6387644/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 15:41:47  来源:igfitidea点击:

builder.parse((new StringReader(xml)) returns DeferredDocumentImpl

java

提问by user393381

I am trying to understand what mistake I could have made but can't find the solution.

我试图了解我可能犯了什么错误但找不到解决方案。

public static Document getXMLFromString(String xml) {
        org.w3c.dom.Document doc = null;
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory
                    .newInstance();
            factory.setNamespaceAware(true);
            DocumentBuilder builder;
            builder = factory.newDocumentBuilder();
            doc = (org.w3c.dom.Document) builder.parse(new InputSource(
                    new StringReader(xml)));
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        return doc;
    }

I did import org.w3c.dom.Document

我确实导入了 org.w3c.dom.Document

I am calling this method here:

我在这里调用这个方法:

private Node getAuthToken(SOAPMessage responseAuth) throws SOAPException,
            TransformerException, ParserConfigurationException, IOException,
            SAXException {
        String s = indentXML(responseAuth.getSOAPPart().getContent());
        Document doc = getXMLFromString(s);
        NodeList authTokenNodeList = doc.getElementsByTagName("authToken");
        return authTokenNodeList.item(0);
    }

The NodeList is empty.

NodeList 是空的。

After researching on the web, everybody uses this code to parse a string to a Document. I do not have any exception but after calling the method parse(), the value of doc is set to [#document: null] DeferredDocumentImpl.

网上查了下,大家都是用这段代码把一个字符串解析成一个Document的。我没有任何异常,但是在调用方法 parse() 之后,doc 的值被设置为 [#document: null] DeferredDocumentImpl。

I am using everything from the org.w3c.dom.

我正在使用 org.w3c.dom 中的所有内容。

xml is a string that contains

xml 是一个字符串,包含

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<context xmlns="urn:zimbra">
<session id="36" type="admin">36</session>
<change token="251"/>
</context>
</soap:Header>
<soap:Body>
<AuthResponse xmlns="urn:zimbraAdmin">
<authToken>...</authToken>
<lifetime>...</lifetime>
<a n="zimbraIsDomainAdminAccount">false</a>
<session id="36" type="admin">36</session>
</AuthResponse>
</soap:Body>
</soap:Envelope>

Here is how I built the string after a SOAP call:

以下是我在 SOAP 调用后构建字符串的方式:

String xml = indentXML(responseAuth.getSOAPPart().getContent());

What am I doing wrong?

我究竟做错了什么?

This is what I am trying to do in a simple way:

这就是我试图以一种简单的方式做的事情:

StringBuilder soapResponse = new StringBuilder(...
...
...
);

        org.w3c.dom.Document doc = null;
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory
                    .newInstance();
            factory.setNamespaceAware(true);
            DocumentBuilder builder;
            builder = factory.newDocumentBuilder();
            doc = (org.w3c.dom.Document) builder.parse(new InputSource(
                    new StringReader(soapResponse.toString())));
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        NodeList authTokenNodeList = doc.getElementsByTagName("authToken");
        Node n = authTokenNodeList.item(0);
        String s = n.getNodeValue();

回答by Jon Skeet

EDIT: Looking at your updated code, I think this is the problem:

编辑:查看您更新的代码,我认为这是问题所在:

String s = n.getNodeValue();

If you look at the docs for Nodeyou'll see that getNodeValue()is defined to return nullfor elements... hence the problem. My sample code uses getTextContent()instead, which works fine.

如果您查看Node的文档,您会看到它getNodeValue()被定义为返回null元素……因此是问题所在。我的示例代码getTextContent()改为使用,效果很好。



It looks like that's just going to defer expanding in-memory objects until they're required.

看起来这只会推迟扩展内存中的对象,直到需要它们为止。

Have you tried calling methods on the returned document rather than just looking in the debugger? I suspect everything is actually working as intended. If not, please post a short but completeprogram which shows it misbehaving. (Note that in the sample you've given, you haven't even shown how builderis set, and you haven't used factory.)

您是否尝试过在返回的文档上调用方法,而不仅仅是在调试器中查看?我怀疑一切实际上都按预期工作。如果没有,请发布一个简短但完整的程序,以显示其行为不端。(请注意,在您提供的示例中,您甚至没有显示如何builder设置,也没有使用factory.)

EDIT: The code you've given works for me. Here's a quick-and-dirty - but importantly, complete- program (using Guavato load the XML file into a string) which shows the node being found successfully:

编辑:您提供的代码对我有用。这是一个快速但重要的完整程序(使用Guava将 XML 文件加载到字符串中),它显示已成功找到节点:

import org.w3c.dom.*;
import org.xml.sax.*;
import java.text.*;
import java.util.*;
import javax.xml.parsers.*;
import java.io.*;
import com.google.common.base.*;
import com.google.common.io.*;

public class Test {

    public static void main(String[] args) throws Exception {
        String xml = Files.toString(new File("test.xml"), Charsets.UTF_8);
        Node node = getAuthToken(xml);
        System.out.println(node.getTextContent());
    }

    private static Node getAuthToken(String xml) throws Exception {
        Document doc = getXMLFromString(xml);
        NodeList authTokenNodeList = doc.getElementsByTagName("authToken");
        return authTokenNodeList.item(0);
    }

    public static Document getXMLFromString(String xml) throws Exception {
        Document doc = null;
        DocumentBuilderFactory factory = DocumentBuilderFactory
            .newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder;
        builder = factory.newDocumentBuilder();
        doc = builder.parse(new InputSource(new StringReader(xml)));
        return doc;
    }
}