views:

35

answers:

1

Hi all,

I am trying to use XPath to get a list of all the persistence units in persistence.xml and am having trouble. The one that I thought would work was:

//persistence/persistence-unit

*

The latter gives me the persistence child which is at least something, I can then manually iterate through, but that defeats the purpose of XPath.

Here is a snippet of my persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
             version="1.0">
    <persistence-unit name="default" transaction-type="RESOURCE_LOCAL">

Any ideas?

Walter

+1  A: 

This is a FAQ. Whenever the XML document has a default namespace declared, any non-prefixed node-tests in an XPath expression are considered to be in "no namespace". The XPath expression doesn't select the required nodes, because their names aren't in "no namespace" but are in the declared default namespace:

Solution (either):

  1. Register the default namespace and associate it to a prefix (say "xxx"). Read the documentation of the particular XPath engine (host) you are using to understand how exactly to do this. Then use this XPath expression: //xxx:persistence/persistence-unit

  2. Use: //*[name()='persistence']/*[name()='persistence-unit']

Last, but not least, try to avoid using the // abbreviation, because it often leads to anomalies and also can be very inefficient.

For example, if you know that all persistence-unit elements are children of the top element, then use:

/*/xxx:persistence-unit
Dimitre Novatchev
ah, brilliant catch. I will give tht a go.
just tested it, it works perfectly.