query to get element that has particular value using xpath - java

I doubt there is a way to get the element which has a particular value (text) from xml document using xpath.
Example doc:
<domain log-root="/logs" application-root="/applications"><resources>
<jdbc-resource pool-name="SamplePool" jndi-name="jdbc/sample" />
<jdbc-resource pool-name="TimerPool" jndi-name="abc">text1</jdbc-resource>
<jdbc-resource pool-name="TimerPool" jndi-name="def">text2</jdbc-resource>
<jdbc-resource pool-name="TimerPool" jndi-name="ghi">text3</jdbc-resource></resources</domain>
Example xPath Query:
/domain//jdbc-resource[#pool-name='TimerPool']/text()='text2'
Please post your ideas if there is any.

Use:
/domain/*/jdbc-resource[#pool-name='TimerPool' and .='text2']
or you may use:
/domain/*/jdbc-resource[#pool-name='TimerPool'][.='text2']
Both expressions above select all jdbc-resource elements the string value of whose pool-name attribute is "TimerPoool" and whose string value (of the jdbc-resource element) is "text2" and that are grand-children of the top element of the XML document.

Well, text() should do. http://www.w3schools.com/xpath/xpath_examples.asp
Have you tried it already? Also, check the path, it could be
//jdbc-resource[#pool-name='TimerPool']/text()='text2'
or
/domain/resource/jdbc-resource[#pool-name='TimerPool']/text()='text2'
or
//resource/jdbc-resource[#pool-name='TimerPool']/text()='text2'

Related

JDOM2 xpath finding nodes within a different namespace

I'm attempting to use JDOM2 in order to extract the information I care about out of a XML document. How do I get a tag within a tag?
I have been only partially successful. While I have been able to use xpath to extract <record> tags, the xpath query to extract the title, description and other data with in the record tags has been returning null.
I've been using Xpath successfully to extract <record> tags out of the document. To do this I use the follwing xpath query: "//oai:record" where the "oai" namespace is a namespace I made up in order to use xpath.
You can see the XML document I'm parsing here, and I've put a sample below: http://memory.loc.gov/cgi-bin/oai2_0?verb=ListRecords&set=cwp&metadataPrefix=oai_dc
<record>
<header>
<identifier>oai:lcoa1.loc.gov:loc.pnp/cph.3a02293</identifier>
<datestamp>2009-05-27T07:22:37Z</datestamp>
<setSpec>cwp</setSpec>
<setSpec>lcphotos</setSpec>
</header>
<metadata>
<oai_dc:dc xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
<dc:title>Jubal A. Early</dc:title>
<dc:description>This record contains unverified, old data from caption card.</dc:description>
<dc:date>[between 1860 and 1880]</dc:date>
<dc:type>image</dc:type>
<dc:type>still image</dc:type>
<dc:identifier>http://hdl.loc.gov/loc.pnp/cph.3a02293</dc:identifier>
<dc:language>eng</dc:language>
<dc:rights>No known restrictions on publication.</dc:rights>
</oai_dc:dc>
</metadata>
</record>
If you look in the larger document you will see that there is never a "xmlns" attribute listed on any of the tags. There is also the matter of there being three different namespaces in the document ("none/oai", "oai_dc", "dc").
What is happening is that the xpath is matching nothing, and evaluateFirst(parent) is returning null.
Here is some of my code to extract the title, date, description etc. out of the record element.
XPathFactory xpf = XPathFactory.instance();
XPathExpression<Element> xpath = xpf.compile("//dc:title",
Filters.element(), null,
namespaceList.toArray(new Namespace[namespaceList.size()]));
Element tag = xpath.evaluateFirst(parent);
if(tag != null)
{
return Option.fromString(tag.getText());
}
return Option.none();
Any thoughts would be appreciated! Thanks.
In your XML, dc prefix mapped to the namespace uri http://purl.org/dc/elements/1.1/, so make sure you declared the namespace prefix mapping to be used in the XPath accordingly. This is part where the namespace prefix declare in your XML :
<oai_dc:dc
xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/
http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
XML parser only see the namespace explicitly declared in the XML, it won't try to open the namespace URL since namespace is not necessarily a URL. For example, the following URI which I found in this recent SO question is also acceptable for namespace : uuid:ebfd9-45-48-a9eb-42d

Why is DOM doing this? (Wrong nodeName XML)

I have this XML (just a little part.. the complete xml is big)
<Root>
<Products>
<Product ID="307488">
<ClassificationReference ClassificationID="AR" Type="AgencyLink"/>
<ClassificationReference ClassificationID="AM" Type="AgencyLink">
<MetaData>
<Value AttributeID="tipoDeCompra" ID="C">Compra Centralizada</Value>
</MetaData>
</ClassificationReference>
</Product>
</Products>
</Root>
Well... I want to get the data from the line
<Value AttributeID="tipoDeCompra" ID="C">Compra Centralizada</Value>
I'm using DOM and when I use nodoValue.getTextContent() I got "Compra Centralizada" and that is ok...
But when I use nodoValue.getNodeName() I got "MetaData" but I was expecting "Value"
What is the explanations for this behaviour?
Thanks!
Your nodeValuevariable most likely points to the MetaData node, so the returned name is correct.
Note that for an element node Node.getTextContent() returns the concatenation of the text content of all child nodes. Therefore in your example the text content of the MetaData element is equal to the text content of the Value element, namely Compra Centralizada.
I guess your are getting the Node object using getElementsByTagName("MetaData"). In this case nodoValue.getTextContent() will return the text content correctly but to get the node name you need to get the child node.
Your current node must be MetaData and getTextContent() will give all the text within its opening and closing tags. This is because you are getting
Compra Centralizada
as the value. You should get the first child using getChildNodes() and then can get the Value tag.

What can I do to select an attribute value using XPATH query?

I am pretty new in XPATH and I have the following problem:
I have this XML content:
<root><status>
<id>0</id>
<message>MY MESSAGE</message>
</status>
<drivers>
<drive id="my ID">
<property1>0</property1>
<property2>104857600</property2>
<property3 />
</drive></drivers>
</root>
What have I to do to select the attribute value named id (I wanto select the "my ID value)
Can you help me?
Tnx
Andrea
To get the attribute node, you can do:
/root/drivers/drive/#id
or
/root/drivers/drive/attribute::id
In most cases this will automatically be converted to a string ('atomized') for you, but in a case where you need to ensure that you are getting back a string value, you can also do:
/root/drivers/drive/#id/string()
This should work:
/root/drivers/drive[1]/#id/text()
equivalent to:
//drive[1]/#id/text()
See there for more XPATH syntax explanation: http://www.w3schools.com/xpath/xpath_intro.asp

Return type of node itself in xpath

Having the following xml
<xml>
<property href="abc">b</property>
<element attr="def">k</element>
</xml>
How can I make the following xpath return literally element.
*[#attr='def']
On it's own this might seem a weird thing to do, but using the above xpath I can't find the node type itself (only the attributes and children).
If you want the name of an element node then use name(*[#attr = 'def']) or local-name(*[#attr = 'def']).

Check whether XML tag exist in Java

I am parsing an XML javax.xml, but i want to know whether a tag exist on a child node For example
<tag>
<child>
<special_tag>Special</special_tag>
<normal_tag>Normal</normal_tag>
</child>
<child>
<normal_tag>Normal</normal_tag>
</child>
</tag>
I am trying to know which Child has Special tag and which doesnt
Using xPath:
//child[special_tag]
Build the DOM for your xml and use XPath to query for the existence of "special_tag" using //special_tag
It seems that this is a classic usecase for SAX.
You should register your listener and check the tag name. When it equals to special_tag get the element's parent.

Categories