【问题标题】:builder.parse((new StringReader(xml)) returns DeferredDocumentImplbuilder.parse((new StringReader(xml)) 返回 DeferredDocumentImpl
【发布时间】:2011-09-17 06:36:32
【问题描述】:

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

公共静态文档 getXMLFromString(String xml) {
        org.w3c.dom.Document 文档 = null;
        尝试 {
            DocumentBuilderFactory 工厂 = DocumentBuilderFactory
                    .newInstance();
            factory.setNamespaceAware(true);
            文档构建器;
            builder = factory.newDocumentBuilder();
            doc = (org.w3c.dom.Document) builder.parse(new InputSource(
                    新的 StringReader(xml)));
        } 捕捉(SAXException e){
            e.printStackTrace();
        } 捕捉(IOException e){
            e.printStackTrace();
        } 捕捉(ParserConfigurationException e){
            e.printStackTrace();
        }
        返回文件;
    }

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

我在这里调用这个方法:

私有节点 getAuthToken(SOAPMessage responseAuth) 抛出 SOAPException, TransformerException、ParserConfigurationException、IOException、 SAX 异常 { 字符串 s = indentXML(responseAuth.getSOAPPart().getContent()); 文档 doc = getXMLFromString(s); NodeList authTokenNodeList = doc.getElementsByTagName("authToken"); 返回 authTokenNodeList.item(0); }

NodeList 为空。

在网上研究后,大家使用这段代码将字符串解析为文档。我没有任何异常,但是在调用方法 parse() 之后,doc 的值被设置为 [#document: null] DeferredDocumentImpl。

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

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>

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

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

我做错了什么?

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

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

        org.w3c.dom.Document 文档 = null;
        尝试 {
            DocumentBuilderFactory 工厂 = DocumentBuilderFactory
                    .newInstance();
            factory.setNamespaceAware(true);
            文档构建器;
            builder = factory.newDocumentBuilder();
            doc = (org.w3c.dom.Document) builder.parse(new InputSource(
                    新的 StringReader(soapResponse.toString())));
        } 捕捉(SAXException e){
            e.printStackTrace();
        } 捕捉(IOException e){
            e.printStackTrace();
        } 捕捉(ParserConfigurationException e){
            e.printStackTrace();
        }
        NodeList authTokenNodeList = doc.getElementsByTagName("authToken");
        节点 n = authTokenNodeList.item(0);
        字符串 s = n.getNodeValue();

【问题讨论】:

  • 文件的内容是什么,可变的xml是什么?
  • 您能否像 Jon Skeet 在他的回答中所说的那样向我们展示您导入的完整代码
  • 刚刚编辑了我的消息,谢谢大家的帮助,我真的不明白这是怎么回事。
  • 如果 XML 来自文件,您是否尝试过使用 parse 方法从文件中读取它??
  • XML 是我在进行 SOAP 调用后收到的。 String xml = indentXML(responseAuth.getSOAPPart().getContent());

标签: java


【解决方案1】:

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

String s = n.getNodeValue();

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


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

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

编辑:您提供的代码对我有用。这是一个简单粗暴的 - 但重要的是,complete - 程序(使用 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;
    }
}

【讨论】:

  • 是的,我确实尝试使用我知道存在的标记元素调用 getElementsByTagName() 方法。
  • @user393381:不,请发布一个简短但完整的程序 - 我可以编译和运行,它会显示问题。
  • @user393381:我现在用我自己的一个简短但完整的程序更新了我的答案。您可能想尝试一下...
  • 我刚刚发布了一个代码 thqt 对我不起作用。我还是不明白。我会试试你的代码。
  • @Jon Skeet:你说的都是对的。正如您所怀疑的,它已经正常工作了,我使用的是 getNodeValue() 而不是 getTextContent()。文字内容是我想要的,我正在尝试找出两者之间的区别。
猜你喜欢
  • 1970-01-01
  • 2013-11-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-04
  • 2019-07-04
  • 2020-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多