XML Value of a node while parsing using DOM - java

I am trying to get the XML value of a node.
To get the Nodelist i am doing this
NodeList list = (NodeList) doc.getElementsByTagName("response")
To get particular Node I am doing:
list.item(index);
From the node i can get the text content of the node but I don't know how to get the XML String value of a node.
For example:
<add job="351">
<test>
<tag>foobar</tag>
<tag>foobar2</tag>
</test>
</add>
I can pick the node with tag "test". Now from the Node i want output like this:
<test>
<tag>foobar</tag>
<tag>foobar2</tag>
</test>
Any help is appreciated.

Related

How to get only first level nodes with Jsoup

I have following XML tree and I'm using Jsoup to parse it.
<?xml version="1.0" encoding="UTF-8" ?>
<nodes>
<node>
<name>NODE 1</name>
<value1>
<value1>NODE 1 VALUE 1</value1>
</value1>
<nodes>
<node>
<name>NODE 1 CHILD</name>
<value1>NODE 1 CHILD VALUE 1</value1>
</node>
</nodes>
</node>
<node>
<name>NODE 2</name>
<value1>NODE 2 VALUE 1</value1>
</node>
</nodes>
However when I try to get only first level of node-elements. It returns all elements including children nodes, and it is doing it correctly, because clearly child elements also match my query.
Elements elements = data.select("nodes > node");
Is there any way to get just first level node-elements without adding additional level information to XML data?
You can do something like this:
Elements elements = data.select("nodes").first().select("> node");
This will work as well:
Elements elements = data.select("> nodes > node");
but only if you've used Jsoup.parse(xml, "", Parser.xmlParser()) to parse the XML and the XML is indeed as you've specified in your question (<nodes> is the root element)

Add XML element in a child node if parent node meets a condition

I have a very simple question for you experts of XML.
I want to add a new Element beside tuple_centre_name, with the same tag and different value, only if the username have a value I want, and another tuple_centre_name with the same value, here amministrazione, does NOT exist.
I ask you because I find difficult to reach that element, check if another tuple_centre_name exists and then check the parent attribute.
I'm using DOM in JAVA.
Thanks for helping me.
<?xml version="1.0" encoding="UTF-8" standalone="no"?><accounts>
<account>
<username>fabio</username>
<password>123456</password>
<node>
<tuple_centre_name>amministrazione</tuple_centre_name>
<port>NP</port>
</node>
</account>
Example is shown here. Request: add a new tuple_centre_name named something else only if it does not already exist inside the element named fabio. Here, is the result I want:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><accounts>
<account>
<username>fabio</username>
<password>123456</password>
<node>
<tuple_centre_name>amministrazione</tuple_centre_name>
<tuple_centre_name>Something else</tuple_centre_name> //ok because `fabio` as username is fine for me
<port>NP</port>
</node>
</account>
You want XPath for this:
Document document = /* ... */;
final String username = "fabio";
XPathVariableResolver resolver = new XPathVariableResolver() {
#Override
public Object resolveVariable(QName varName) {
return varName.getLocalPart().equals("user") ? username : null;
}
};
Element newElement = document.createElement("tuple_centre_name");
newElement.appendChild(document.createTextNode("amministraione"));
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setXPathVariableResolver(resolver);
Node tupleCentreNameNode = (Node) xpath.evaluate(
"//account[username[text()=$user]]/node/tuple_centre_name",
document,
XPathConstants.NODE);
tupleCentreNameNode.getParentNode().insertBefore(newElement,
tupleCentreNameNode.getNextSibling());
XPath usually looks like a directory path, which is where the account/node/tuple_centre_name part comes from. The two slashes at the start (//account) means "any account element, any number of levels deep in the document."
The account[username[text()=$user]] selector means "an account element which contains a username element whose text matches the XPath variable 'user'." XPath variables can be defined externally with an XPathVariableResolver. While it is possible to hard-code the username value in the XPath expression, you would need to escape various characters, including quotes and characters which are special in XML; passing the username as an XPath variable guarantees it will be correct.

Get child nodes by searching for parent node using XPath

My XML structure is as under
<Employee>
<categoryType>Name</categoryType>
<groupNames>
<name>ABC</name>
<name>XYZ</name>
<name>PQR</name>
</groupNames>
</Employee>
I am trying to get hold of the child nodes by searching for parent node (categoryType = Name ).
Tried using all the following combinations , but none of them return the child nodes.
//*[contains(#categoryType,'Name')]/groupNames
Employee/*(#categoryType,'Name')/groupNames
Any suggestions would be appreciated.
You are matching an attribute categoryType which doesn't exist. You have to match an element. Replace #categoryType for categoryType and you will have a different result.
This:
//*[contains(categoryType,'Name')]/groupNames
will get the categoryType node. And this:
//*[contains(categoryType,'Name')]/groupNames/name
will return a node-set with all three names.

Using XQuery in Java to extract CData from an xml file

I've got a kml file(essentially xml) which has a set of nodes; name, description, coordinates etc. Up until now I have only been getting two values; name and coordinates. Now I want to get the description data as well, the only problem is that it is CData and when parsed it is ignored.
I've been using XQuery to get the data so far;
XPathExpression expr = xpath.compile("//name/text()");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for...
In the kml file its just <![CDATA[.....]>as opposed to "101" (an actual string) Using the same query it returns nothing.
The kml file has structure:
<Document>
<Placemark>
<name>101</name>
<description><![CDATA[.....]]></description>
<polygon>
<coordinates>......</coordinates>
</polygon>
</Placemark>
<Placemark>
....
</Placemark>
</Document>
Is there a way to do it through XQuery?
Use the following XPath expression i.e. without specifying text():
XPathExpression expr = xpath.compile("//description");
and read the CDATA content with node.getTextContent()

Query Node in XOM

I am querying document in XOM, getting a Node, and then querying this Node for another Node. However, querying Node behaves like it's querying whole document, not only this node.
XML is like this:
<root>
<someotherstuff>
<DifferentNode>
<Value1>different-value1</Value1>
</DifferentNode>
<Node>
<Node>
<Value1>value1</Value1>
<Value2>value2</Value2>
</Node>
<Node>
<Value1>value3</Value1>
<Value2>value4</Value2>
</Node>
<!-- more Node's -->
</Node>
</someotherstuff>
</root>
And I'm doing this:
Nodes nodes = document.query("//Node/Node", X_PATH_CONTEXT);
Node node = nodes.get(0);
Nodes innerNodes = node.query("/Value1");
And innerNodes contains 0 children. When I change "/Value1" to "//Value1" (slash added) then I'm getting different-value1, so it looks like it's querying whole document, instead of my selected Node.
How can I query specific Node in XOM?
When your query starts with a single slash then this looks for the document root node with the given name. Two slashes in contrast means to look for all ancestors of the given name. Your query should work if you simply omit the leading slash:
Nodes innerNodes = node.query("Value1");

Categories

Resources