How to fetch a value from XML using XPATH - java

This is my xml and i wanted to fetch value of Id tag '4654'
<Entity>
<acc>
<id>4654</id>
<name>abc</name>
</acc>
<acc>
<id>5465</id>
<name>xyz</name>
</acc>
I am using this code to retrieve the Id value
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(xml)));
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList node = (NodeList) xPath.evaluate("/Entity/acc/id/text()", document, XPathConstants.NODE);
System.out.println("node length:"+node.getLength());
System.out.println("node value:"+ node.item(0).getNodeValue());
return node.item(0).getNodeValue();
Output returns null
Any help would be appreciated

You need to use XPathConstants.NODESET instead of XPathConstants.NODE
or you can keep it as XPathConstants.NODE and change the evaluate to return Node
Node node = (Node) xPath.evaluate("/Entity/acc/id/text()", document, XPathConstants.NODE);

Related

How to read child XML using XPath in Java

The XML file is as :
Xml File
Code I have written:
List queryXmlUsingXpathAndReturnList(String xml, String xpathExpression) {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance()
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder()
Document doc = dBuilder.parse(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)))
doc.getDocumentElement().normalize()
XPath xPath = XPathFactory.newInstance().newXPath()
NodeList nodeList = (NodeList) xPath.compile(xpathExpression).evaluate(doc, XPathConstants.NODESET)
List returnElements = new ArrayList<>()
nodeList.each { n ->
returnElements.add(n.getTextContent())
}
When I am passing the xpath as:
/Envelope/Body/CommandResponseData/OperationResult/Operation/ParameterList/ListParameter/StringElement
It returns all the values.
But I want to return only the ListParameter values whose name="PackageTypeList".
For that I am using the xpath as:
/Envelope/Body/CommandResponseData/OperationResult/Operation/ParameterList/ListParameter[#name='PackageTypeList']/StringElement
But it returns list as null.
I guess you miss "CommandResult" between "CommandResponseData" and "OperationResult" in your XPath-Expression.

How do I return a subsection of an XML request based on an XPath expression

I have written code that enables me to a subsection of an xml request based on a given XPath, however, it is only the value between the tags that are returned and not the tags.
I want both values and elements to be returned based on a given xpath.
For example, in this xml:
?xml version="1.0"?>
<company>
<staff1>
<name>john</name>
<phone>465456433</phone>
<email>gmail1</email>
<area>area1</area>
<city>city1</city>
</staff1>
<staff2>
<name>mary</name>
<phone>4655556433</phone>
<email>gmail2</email>
<area>area2</area>
<city>city2</city>
</staff2>
<staff3>
<name>furvi</name>
<phone>4655433</phone>
<email>gmail3</email>
<area>area3</area>
<city>city3</city>
</staff3>
</company>
my XPath would only return the value of the first staff element i.e.
John
465456433
gmail1
area1
city1
It does not return the tags associated to it i.e, it should return the following:
<staff1>
<name>john</name>
<phone>465456433</phone>
<email>gmail1</email>
<area>area1</area>
<city>city1</city>
</staff1>
Here is my code:
InputSource inputSource = new InputSource(new StringReader(xmlString));
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
String RecordCategory;
Document doc = documentBuilderFactory.newDocumentBuilder().parse(inputSource);
// Create XPathFactory object
XPathFactory xpathFactory = XPathFactory.newInstance();
// Create XPath object
XPath xpath = xpathFactory.newXPath();
System.out.println("TESTING XPATH");
xpath.setNamespaceContext(new NamespaceContext() {
#Override
public String getNamespaceURI(String prefix) {
...
});
XPathExpression expr = xpath.compile("//staff1[1]");
Staff1 = (String) expr.evaluate(doc,XPathConstants.STRING);
System.out.println("staff1: " + staff1);
Anyone have any idea on what I could do to resolve this issue?
Your Java call to XPathExpression.evaluation() is returning the string value of the node selected by your XPath expression. If you instead want to return the node selected by your XPath expression, change
Staff1 = (String) expr.evaluate(doc, XPathConstants.STRING);
to
Node node = (Node) expr.evaluate(doc, XPathConstants.NODE);
See this answer for how to pretty print node.

How to get Nth parent for an element in xml using Java

I am using w3c dom library to parse XML. Here I need 3rd parent of element .For example in below XML I am using element.getParentNode()
Input XML
<abc cd="1">
<weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0">
<current_conditions>
<condition data="Clear">
<item abc ="1" />
</condition>
<temp_f data="49"/>
<temp_c data="9"/>
</current_conditions>
</weather>
</abc>
I have Element eleItem= /item and have to get to parent /weather I am doing it as :
(Element) eleItem.getParentNode().getParentNode().getParentNode();
Is there any other method or using xpath as this doesn't seem to be the right way ?
something likegetXPathParent(eleItem, "../../..")
You are almost there. You could use XPathFactory of java like below :
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse( new File( "input.xml" ) );
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
XPathExpression expr = xpath.compile ( "//item/../../..");
Object exprValue = expr.evaluate( doc, XPathConstants.NODE );
if ( exprValue != null && exprValue instanceof Node )
{
Node weatherNode = (Node)exprValue;
System.out.println( weatherNode.getNodeName() );
}
How it works?
The xpath //item/../../.. recursively searches for element item and gets its 3rd level parent.
The XPathConstants.NODE in the evaluate tells Java XPath engine to retrieve it as a Node.
Output will be :
weather
EDIT:
- If you have an element as input :
The following code should give the 3rd parent, where element is item.
public Node getParentNodeUsingXPath( Element element )
{
Node parentNode = null;
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
String nodeName = element.getNodeName();
String expression = "//" + nodeName + "/../../..";
Object obj = xpath.evaluate(expression, element, XPathConstants.NODE );
if ( obj != null )
{
parentNode = (Node)obj;
}
return parentNode;
}

Node.getNodeValue() returns null in java

I am trying to find the node value by evaluating the xpath expression.
String resp="<response><result><phone>1234</phone><sys_id>dfcgf34dfg56</sys_id></result></response>";
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = domFactory.newDocumentBuilder();
org.w3c.dom.Document dDoc = builder.parse(new InputSource(new ByteArrayInputStream(resp.getBytes("utf-8"))));
XPath xPath = XPathFactory.newInstance().newXPath();
Node node = (Node) xPath.evaluate("//response/result/sys_id", dDoc, XPathConstants.NODE);
System.out.println(node.getNodeName()+" , "+node.getNodeValue());
This gives the output : sys_id , null when the sys_id is clearly not null.
The xpath evaluator returns correct value.
Can anybody point out any error?
Thank you!
I am not an expert in XPath, but based on this Stack Overflow article I was able to produce the following code which does work correctly:
String resp = "<response><result><phone>1234</phone><sys_id>dfcgf34dfg56</sys_id></result></response>";
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = domFactory.newDocumentBuilder();
org.w3c.dom.Document dDoc = builder.parse(new InputSource(new ByteArrayInputStream(resp.getBytes("utf-8"))));
XPath xPath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xPath.compile("//response/result/sys_id"); // these 2 lines
String str = (String) expr.evaluate(dDoc, XPathConstants.STRING); // are different
System.out.println(str);
Output:
dfcgf34dfg56
There is a typo in your code: When parsing the input you use a variable called "resp" but you defined a vaiable called "resp1".
Dispite the typo: In order to catch the TextContent use node.getTextContent()
System.out.println(node +": " + node.getNodeName() + ", " + node.getTextContent());
The reason why your code returned null is: You are extracting an ELEMENT node and the result of getNodeValue() depends on the node type (see table in API) and will always return null for ELEMENT nodes.

java dom search xml

hello i have this xml
<?xml version="1.0" encoding="utf-8" standalone="no"?><?xml-stylesheet type="text/xsl" href="new2.xsl"?>
<patients>
<patient>
<stoixeia_astheni>
<arithmos_eksetasis>1</arithmos_eksetasis>
<imerominia_eksetasis>11/12/2005</imerominia_eksetasis>
<amka>14385</amka>
</stoixeia_astheni>
<stoixeia_epikoinonias>
<dieuthinsi>Μητσοπούλου 20</dieuthinsi>
</stoixeia_epikoinonias>
<loipa_stoixeia>
<fylo>Aρρεν</fylo>
</loipa_stoixeia>
</patient>
<patient>
same code here
</patient>
</patients>
and i want to search this by amka value.
i have tried this:
Document doc = docBuilder.parse(filepath);
NodeList root= doc.getDocumentElement().getChildNodes();
for(int i=0; i<root.getLength(); i++){
if(root.item(i).getChildNodes().item(0).getChildNodes().item(2).getNodeValue()=="14385"){
pw.println("Gataki<br>");
}
}
but runtime error occurs
Any help would be useful.
Use this xpath
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(<uri_as_string>);
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("/patients/patient/stoixeia_astheni/amka/text()");
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
Just in case takke a look at this xpath syntaxis
/ Selects from the root node
// Selects nodes in the document from the current node that match the selection no matter where they are
. Selects the current node
.. Selects the parent of the current node
# Selects attributes

Categories

Resources