How to get the element from the xml using Xpath Java - java

<employees>
<employee>
<firstName>Lokesh</firstName>
<lastName>Gupta</lastName>
<department>
<id>101</id>
<name>IT</name>
</department>
</employee>
</employees>
I wanted to get the elements name using Xpath..
I need to count the number of elements that i am getting using count(//employees/*) and count(//employees/employee/department/*)
it is returning count of each parent..
I need to get the element names as well //employees/employee/*/name() to get the elements name FirstName, LastName and Department..
also (//employees/employee/department/*/name()) to return name and id.. but it is showing error javax.xml.transform.TransformerException: Unknown nodetype: name .

You want to get the elements names (not the value of it). name() has to appear the first.
Since javax only supports XPath 1.0, you can use :
concat(name(//employees/employee/*[1]),",",name(//employees/employee/*[2]),",",name(//employees/employee/*[3]))
Output : firstName,lastName,department
concat(name(//employees/employee/department/*[1]),",",name(//employees/employee/department/*[2]))
Output : id,name
If you don't know the number of child for each parent element, you should use a loop approach. First, count and store the number of child (count(//employees/employee/*)), then make a loop where you increase the position index ([i]) at each iteration //employees/employee/*[i] i=i+1.

Related

Is it possible to scan an xml element using single Xpath expression when the element is case insensitive [duplicate]

This question already has answers here:
case-insensitive matching in XPath?
(6 answers)
Case insensitive XPath contains() possible?
(6 answers)
Closed 5 years ago.
I have below XML which I need to parse.I need to take name value.But the name element might be case insensitive.How to write a generic Xpath epression to read element with name or Name?
<Employees>
<Employee id="1">
<age>29</age>
<name>Pankaj</name>
<gender>Male</gender>
<role>Java Developer</role>
</Employee>
<Employee id="2">
<age>35</age>
<Name>Lisa</Name>
<gender>Female</gender>
<role>CEO</role>
</Employee>
</Employees>
Below expression will good for name element when we give id as dynamic value.
XPathExpression:
exprs = xpath.compile("/Employees/Employee/#id" + id+ "']/name/text()");
Try below XPath to match both name and Name elements
/Employees/Employee/*[matches(name(), "name", "i")]/text()
/*[matches(name(), "name", "i")] should match any element (*) which name (name()) is equal to "name" ignoring ("i") case
You can try the XPath translate() function :
translate(string1,string2,string3)
Converts string1 by replacing the characters in string2 with the characters in string3
In your case, the following:
//Employee/*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='name']";
will:
For each Employee
Check each children
Convert all letter in the name of the child ( local-name() ) that are Uppercase to lowercase
Compare it to "name"
With this, you don't have to check manually for each possibility and can be re-use for anything else too ; you just have to replace "name" by tho word you want to check.
For futher reading:
translate() --> https://developer.mozilla.org/fr/docs/XPath/Fonctions/translate
local-name() --> https://developer.mozilla.org/fr/docs/XPath/Fonctions/local-name

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.

reading redundant xml tags in java

I want to read an xml file like
<config>
<name>empData</name>
<employee>
<emp-name>Tom</emp-name>
<emp-age>25</emp-age>
<emp-lang>English</emp-lang>
<emp-lang>French</emp-lang>
</employee>
</config>
can have more than 1 employee and each employee can have more than 1 tag.
I want to store each employee's data in a list.
How can I do the same.
I am using
for(int j=0;j<lengthHeader;j++){
xmlDataModel = new XMLDataModel();
xmlDataModel.setEmpLang( e.getElementsByTagName("emp-lang").item(k).getChildNodes().item(j).getNodeValue());
}
where k is the variable for employee tag and j is for emp laguage tag.
with this it is retrieving only 1st value and after that it is throwing null pointer exception and if I use item(j).item(0) ,then it is retrieving emp-lang for all employees,I want only for each employee tag separately.
Thanks

how to add an attribute to an XML element

I am using the DOM parser. I have to parse the following XML:
<abc>
<type action="">
<code>test</code>
<value>001</value>
</type>
<type action="">
<code>test2</code>
<value>002</value>
</type>
</abc>
so, depending on the value field under the type field, I have to fill in the action attribute in the type field. I am a bit stumped. I am able to get the value of the value field, but I don't know how to go back and add the attribute.
Any help will be appreciated a lot!!!
thanks!
To go back, just save a reference to the type Element before you traverse to its value child. (assuming you visited it already).
to change the value, use the setAttribute() method.
edit:
Alternate method: from the value text node, call getParentNode() twice (once to get back to the value element & once to get back to the type element), then call setAttribute() after you do any necissary casting.
try something like
nodelist = doc.getElementsByTagName("value");
for (Element element : nodelist) {
Element parent = element.getParentNode()
parent.setAttribute("action", "attrValue");
}

How do I select something with a blank namespace with Jaxen?

I have the following xml:
<config xmlns="http://www.someurl.com">
<product>
<brand>
<content />
</brand>
</product>
</config>
I'm reading it nicely into JDOM.
However, when I try to use Jaxen to grab the contents, I can't seem to get anything.
Here's an example of what doesn't seem to work:
XPath xpath = new JDOMXPath("config");
SimpleNamespaceContext namespaceContext = new SimpleNamespaceContext();
namespaceContext.addNamespace("", "http://www.someurl.com");
xpath.setNamespaceContext(namespaceContext);
assert xpath.selectNodes(document).size() > 0 : "should find more than 0";
This assertion always fails.
What am I doing wrong?
You have to assign a prefix. Make that call addNamespace("hopfrog", "http://...");
Then make the XPath ("hopfrog:config");
Keep in mind that the prefixes in XML aren't part of the real data model. The real data model assigns a URL, possibly blank, to each element and attribute. You can use any prefix you want in XPath so long as it's bound to the right URL. Since the URL you want it blank, you bind a prefix to 'blank'.

Categories

Resources