Get a Node's Inner Xml as String in Java Dom

Get a node's inner XML as String in Java DOM

Same problem. To solve it I wrote this helper function:

public String innerXml(Node node) {
DOMImplementationLS lsImpl = (DOMImplementationLS)node.getOwnerDocument().getImplementation().getFeature("LS", "3.0");
LSSerializer lsSerializer = lsImpl.createLSSerializer();
NodeList childNodes = node.getChildNodes();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < childNodes.getLength(); i++) {
sb.append(lsSerializer.writeToString(childNodes.item(i)));
}
return sb.toString();
}

JAVA XML : get content Node

The following example will print <country id="98" nom="Espagne"/><country id="76" nom="France"/>:

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.InputSource;
import java.io.StringReader;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ls.LSSerializer;

...

String xml = "<root><countries><country id=\"98\" nom=\"Espagne\"/><country id=\"76\" nom=\"France\"/></countries></root>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xml));
Document doc = builder.parse(is);
Node node = doc.getElementsByTagName("countries").item(0);
String innerXml = getInnerXml(node);
System.out.println(innerXml);

And the helper method getInnerXml(node) looks like this:

private String getInnerXml(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++) {
sb.append(lsSerializer.writeToString(childNodes.item(i)));
}
return sb.toString();
}

Let me know if I have misunderstood the requirement (again!).

The warning here is that this is not a great solution. It involves constructing XML "by hand" (i.e. string concatenation) and that carries some risk that the results will be brittle or even broken, if the input is unexpectedly different or complex.

Java/DOM: Get the XML content of a node

You have to use the transform/xslt API using your <b> node as the node to be transformed and put the result into a new StreamResult(new StringWriter());
. See how-to-pretty-print-xml-from-java

Getting XML Node text value with Java DOM

I'd print out the result of an2.getNodeName() as well for debugging purposes. My guess is that your tree crawling code isn't crawling to the nodes that you think it is. That suspicion is enhanced by the lack of checking for node names in your code.

Other than that, the javadoc for Node defines "getNodeValue()" to return null for Nodes of type Element. Therefore, you really should be using getTextContent(). I'm not sure why that wouldn't give you the text that you want.

Perhaps iterate the children of your tag node and see what types are there?

Tried this code and it works for me:

String xml = "<add job=\"351\">\n" +
" <tag>foobar</tag>\n" +
" <tag>foobar2</tag>\n" +
"</add>";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes());
Document doc = db.parse(bis);
Node n = doc.getFirstChild();
NodeList nl = n.getChildNodes();
Node an,an2;

for (int i=0; i < nl.getLength(); i++) {
an = nl.item(i);
if(an.getNodeType()==Node.ELEMENT_NODE) {
NodeList nl2 = an.getChildNodes();

for(int i2=0; i2<nl2.getLength(); i2++) {
an2 = nl2.item(i2);
// DEBUG PRINTS
System.out.println(an2.getNodeName() + ": type (" + an2.getNodeType() + "):");
if(an2.hasChildNodes()) System.out.println(an2.getFirstChild().getTextContent());
if(an2.hasChildNodes()) System.out.println(an2.getFirstChild().getNodeValue());
System.out.println(an2.getTextContent());
System.out.println(an2.getNodeValue());
}
}
}

Output was:

#text: type (3): foobar foobar
#text: type (3): foobar2 foobar2

java DOM XML Parser Inner Element

To get child in images tag, you can not call getChildNodes in the images tag directly, as there are some additional node, refer to java xml cast Node to Element.
So try to get the child directly by getElementsByTagName.

File fXmlFile=new File("feed.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("item");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
Element eElement2 = (Element) nNode;
int search = 1234;
System.out.println("This is the value to search from my variable: " + search);
int toTest = Integer.parseInt(eElement2.getAttribute("UnitID"));
System.out.println("toTest is equal to: " + toTest);
if (toTest == search) {
System.out.println(
"stock Number: " + eElement2.getElementsByTagName("stock_number").item(0).getTextContent());
Element images = (Element) eElement2.getElementsByTagName("images").item(0);
Element image1Node = (Element) images.getElementsByTagName("Image1").item(0);
Element image2Node = (Element) images.getElementsByTagName("Image2").item(0);
Element image3Node = (Element) images.getElementsByTagName("Image3").item(0);
if (image1Node.getAttribute("image").equals("1")) {
System.out.println("image1Node id attribute is 1");
}
if (image2Node.getAttribute("image").equals("1")) {
System.out.println("image2Node id attribute is 1");
}
if (image3Node.getAttribute("image").equals("1")) {
System.out.println("image3Node id attribute is 1");
}
}
}

Read Inner XML of a XML Element

XPath is what you want. For all intents and purposes, you can think of xpath as you would sql, only it is for xml documents instead of databases. Here is a simple example using Java (keep in mind xpath is a standard and not specific to java, so you can find many ways of doing this in pretty much any popular language):

    // Load document
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse( new FileInputStream( "/tmp/xml" ) );

// Create XPath expression
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile( "//server01" );

// Find node 'server01'
Node node = (Node) expr.evaluate( doc, XPathConstants.NODE );
if( node == null ) {
System.out.println( "Node not found" );
System.exit( 0 );
}

// Extract departments
Element server01 = (Element) node;
for( int k = 0 ; k < server01.getChildNodes().getLength() ; k++ ) {
Node childNode = server01.getChildNodes().item( k );
// Check if current node is a department node
if( "department".equals( childNode.getNodeName() ) ) {
System.out.println( childNode.getNodeName() + ": " + childNode.getTextContent().trim() );
}
}

Is there is a possibility to avoid this?

Yes just change XPath expression an receive only nodes you need.

// Load document
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse( new FileInputStream( "/tmp/xml" ) );

// Create XPath expression
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile( "//server01/department" );

// Find nodes 'department' under node 'server01'
NodeList node = (NodeList) expr.evaluate( doc, XPathConstants.NODESET );

// Extract departments
for( int k = 0 ; k < node.getLength() ; k++ ) {
Node childNode = node.item( k );
// Check if current node is a department node
if( "department".equals( childNode.getNodeName() ) ) {
System.out.println( "[" + k + "] " + childNode.getNodeName() + ": " + childNode.getTextContent().trim() );
}
}

You must receive the next output:

[0] department: A1
[1] department: A2

Java XML Node Inside Node Value

For an Element is defined the method getAttribute("AttributeName").

If you want the name of the cars inside a garage you are doing right by creating a NodeList within all the elements by tag name "garage", then you should create a nested for loop, to get all the elements by tag name "cars" inside your garage.

    for (int temp = 0; temp < NodeOzet.getLength(); temp++){
Node nOzet = NodeOzet.item(temp);
NodeList carList = eElement.getElementsByTagName("cars")
String cars = "";
for(int temp2 = 0; temp2 < carList.getLength(); temp2++){
cars += ((Element)carList.item(temp2)).getAttribute("carname") + "\t";
}
}

Like this for each garage you get all the cars inside the garage, and their names

Get nested xml document in DOm java

Serialize your <iid> node into a string using an LSSerializer.

try {
NodeList childNodes = xmldoc.getDocumentElement().getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if ("InputData".equals(node.getNodeName())) {
Node iid = node.getFirstChild();
while (!"iid".equals(iid.getNodeName())) {
iid = iid.getNextSibling();
}
String iidTree = ((DOMImplementationLS) xmldoc
.getImplementation()).createLSSerializer()
.writeToString(iid);
System.out.println(iidTree.replaceFirst("<.*?>\n", "")
.replaceAll("[ ]", ""));
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}

Output :

<iid>
<test3>p</test3>
<test4>p1</test4>
</iid>

The LSSerializer writes out data as an XML file. The regex substitution just removes the XML header and normalizes the whitespaces.



Related Topics



Leave a reply



Submit