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
builder.parse((new StringReader(xml)) returns DeferredDocumentImpl
提问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 null
for 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 builder
is 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;
}
}