Search child node in XML by sub-node content - java

I'm a noob whith XPath and I have a question: How can I search for a child in all branches by a particular name and display the information in the XML file?
<?xml version="1.0" encoding="UTF-8"?>
<movie><?xml version="1.0" encoding="UTF-8"?>
<movie>
<film>
<name>Peaceful Warrior</name>
<actor>Scott Mechlowicz</actor>
</film>
<film>
<name>Gone</name>
<actor>Scott Mechlowicz</actor>
</film>
<film>
<name>Gladiator</name>
<actor>Russel Crowe</actor>
</film>
</movie>
I tried:
//*[ancestor::movie/film[name = "Scott Mechlowicz"]]
But this shows all the information, when my intention is to show only movies in which that actor participates.
Is this possible with XPath or must I use getNameByTagName NodeList?

You can use XPath. If you are just trying to get a list of names of movies, try this XPath (get name of film where actor = "Scott Mechlowicz")
//film[actor = "Scott Mechlowicz"]/name
or
/movie/film[actor = "Scott Mechlowicz"]/name

Related

Empty default XML namespace xmlns="" attribute being added?

I have simple code where I create root element and append child to it. The problem is that child appends with empty xmlns="" attribute, though I don't expect it. It is a problem only of the first child, and the child of second nesting level is already Ok.
So, the following code -
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
Element rootEl = doc.createElementNS("http://someNamespace.ru", "metamodel");
doc.appendChild(rootEl);
Element groupsEl = doc.createElement("groups");
// This appends with xmlns=""
rootEl.appendChild(groupsEl);
Element groupEl = doc.createElement("group");
// This appends normally
groupsEl.appendChild(groupEl);
Will result to output -
<?xml version="1.0" encoding="UTF-8"?>
<metamodel xmlns="http://someNamespace.ru">
<groups xmlns="">
<group/>
</groups>
</metamodel>
Instead of -
<?xml version="1.0" encoding="UTF-8"?>
<metamodel xmlns="http://someNamespace.ru">
<groups>
<group/>
</groups>
</metamodel>
Note, as I said above, the tag <group> is already free from xmlns.
Your desired markup shows all elements in the default namespace. In order to achieve this, you have to create all elements in the default namespace.
The actual output you're getting has <groups xmlns=""> because groups, and its group child element were created in no namespace:
Element groupsEl = doc.createElement("groups");
Change this to
Element groupsEl = doc.createElementNS("http://someNamespace.ru", "groups");
Similarly, change
Element groupEl = doc.createElement("group");
to
Element groupEl = doc.createElementNS("http://someNamespace.ru","group");

Java appending an element to XML document

I am trying to append an element to my xml document so it looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<students>
</students>
However, it ends up looking like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<students/>
This is the code I am using:
// results is the new XML document I created using DocumentBuilder.newDocument();
Element root = results.createElement("students");
results.appendChild(root);
How come it isn't looking like how I want it to?
Java dom is implemented based on the xml specification, and by definition: An element with no content is said to be empty : https://www.w3.org/TR/REC-xml/#sec-starttags.

Java DOM How to check if node exists in XML

Here is my xml file
<?xml version="1.0" encoding="UTF-8"?>
<productlist>
<product>
<title>1</title>
<price>30</price>
</product>
<product>
<title>2</title>
<price>9</price>
</product>
<product>
<title>3</title>
</product>
</productlist>
What I need to do is use Java DOM API to print out all the contents from XML file which contain "price" tag. Such things like this
title:1
price:30
title:2
price:9
In the org.w3c.dom documentation I only find hasAttribute(String name) method to check if this element have attribute but I can not find method like "hasTag(String name)" in documentation. I find this website http://www.java-forums.org/xml/62136-check-whether-xml-tag-exists-while-parsing-xml-using-dom-java.html but unfortunately I can not open the site. Hope you can help.
Just call getElementsByTagName and see if the returned list has any nodes (using NodeList.getLength()).

XML DOM parsing with Java

I'm trying to parse this XML string:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<response type="success">
<lots>
<lot>32342</lot>
<lot>52644</lot>
</lots>
</response>
When I get the root node, which is "response", I use the method getChildNodes() which returns a NodeList of length 3. However what I'm confused about is the order the NodeList gets created in. I used some print statements to show whats in the list
Item length: 3
Item (0): [#text:
]
Item (1): [lots: null]
Item (2): [#text:
]
So the text node is first which is two levels below the root, then the next child of the root, and then the next text node.
Is there a particular order and/or reason the list is ordered in this way?
You are seeing the whitespace text surrounding the childnode "lots"
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<response type="success">
{txt1}<lots>
<lot>32342</lot>
<lot>52644</lot>
</lots>{txt2}
</response>
Actually I found the problem, I was using '\n' characters which was causing extra text nodes being parsed

Finding all valid xpath from xml

I am trying to write a program in java where in i can find all the xpath for the given xml.I found out the link on the internet xpath generator but it does not work when one element can repeat multipletimes for example if we have xml like the following :-
<?xml version="1.0" encoding="UTF-8"?>
<Report>
<Name>
<FirstName>A</FirstName>
<LastName>B</LastName>
<MiddleName>C</MiddleName>
</Name>
<Name>
<FirstName>D</FirstName>
<LastName>E</LastName>
<MiddleName>S</MiddleName>
</Name>
</Report>
It will produce xpaths :-
/Report/Name/firstname for both firstname nodes.
but the expected should be /Report/Name1/firstname and /Report/Name[2]/firstname
Any ideas?
I think you may have to do this yourself.
Using a SAX parser will make it straightforward. Just maintain a stack of the elements you encounter and a count so you can increment the indexes (/Report/Name[1], /Report/Name[2]) easily.

Categories

Resources