I have an XML org.w3c.dom.Node that looks like this:
<variable name="variableName">
<br /><strong>foo</strong> bar
</variable>
How do I get the <br /><strong>foo</strong> bar part as a String?
I have an XML org.w3c.dom.Node that looks like this:
<variable name="variableName">
<br /><strong>foo</strong> bar
</variable>
How do I get the <br /><strong>foo</strong> bar part as a String?
I want to extend the very good answer from Andrey M.:
It can happen that a node is not serializeable and this results in the following exception on some implementations:
org.w3c.dom.ls.LSException: unable-to-serialize-node:
unable-to-serialize-node: The node could not be serialized.
I had this issue with the implementation "org.apache.xml.serialize.DOMSerializerImpl.writeToString(DOMSerializerImpl)" running on Wildfly 13.
To solve this issue I would suggest to change the code example from Andrey M. a little bit:
private static String innerXml(Node node) {
DOMImplementationLS lsImpl = (DOMImplementationLS) node.getOwnerDocument().getImplementation().getFeature("LS", "3.0");
LSSerializer lsSerializer = lsImpl.createLSSerializer();
lsSerializer.getDomConfig().setParameter("xml-declaration", false);
NodeList childNodes = node.getChildNodes();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < childNodes.getLength(); i++) {
Node innerNode = childNodes.item(i);
if (innerNode!=null) {
if (innerNode.hasChildNodes()) {
sb.append(lsSerializer.writeToString(innerNode));
} else {
sb.append(innerNode.getNodeValue());
}
}
}
return sb.toString();
}
I also added the comment from Nyerguds. This works for me in wildfly 13.
The best solution so far, Andrey M's, needs a specific implementation which can cause issues in the future. Here is the same approach but with just whatever JDK gives you to do the serialization (that means, what is configured to be used).
public static String innerXml(Node node) throws Exception
{
StringWriter writer = new StringWriter();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
NodeList childNodes = node.getFirstChild().getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
transformer.transform(new DOMSource(childNodes.item(i)), new StreamResult(writer));
}
return writer.toString();
}
If you're processing a document rather than a node, you must go one level deep and use node.getFirstChild().getChildNodes(); But, to make it more robust, you should find the first Element, not just take it for granted that there is only one node. XML has to have a single root element, but can multiple nodes, including comments, entities and whitespace text.
Node rootElement = docRootNode.getFirstChild();
while (rootElement != null && rootElement.getNodeType() != Node.ELEMENT_NODE)
rootElement = rootElement.getNextSibling();
if (rootElement == null)
throw new RuntimeException("No root element found in given document node.");
NodeList childNodes = rootElement.getChildNodes();
And if I should recommend a library to deal with it, try JSoup, which is primarily for HTML, but works with XML too. I haven't tested that though.
Document doc = Jsoup.parse(xml, "", Parser.xmlParser());
fileContents.put(Attributes.BODY, document.body().html());
// versus: document.body().outerHtml()