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
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.
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.
I am using everything from the org.w3c.dom.
xml is a string that contains
<?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:
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();
Best Answer
EDIT: Looking at your updated code, I think this is the problem:
If you look at the docs for Node you'll see that
getNodeValue()
is defined to returnnull
for elements... hence the problem. My sample code usesgetTextContent()
instead, which works fine.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 complete program 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 usedfactory
.)EDIT: The code you've given works for me. Here's a quick-and-dirty - but importantly, complete - program (using Guava to load the XML file into a string) which shows the node being found successfully: