7

Lets say i have the following form data instance in my view.xml:

<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xxforms="http://orbeon.org/oxf/xml/xforms"
xmlns:exforms="http://www.exforms.org/exf/1-0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xhtml:head>
<xforms:instance id="instanceData">
    <form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <fruits>
     <fruit>
        <fruit-name>Mango</fruit-name>
     </fruit>
     <fruit>
        <fruit-name>Apple</fruit-name>
     </fruit>
     <fruit>
        <fruit-name>Banana</fruit-name>
     </fruit>
</fruits>
</form>
</xforms:instance>
</xhtml:head>

I want to select all the fruit names from the above instance. I tried the following ways but it always selects the first fruit.

instance('instanceData')/fruits/fruit[*]/fruit-name
instance('instanceData')/fruits/fruit/fruit-name
instance('instanceData')/fruits/fruit[position()>0]/fruit-name

Please provide a way to overcome this in XPATH

Thangamani J
  • 101
  • 1
  • 1
  • 3
  • Beside both expressions are verbose and they could be just `instance('instanceData')/fruits/fruit/fruit-name`, whether an expression results in all the selected nodes or just the first one pretty much depends on the specific XPath engine's method used. –  Mar 03 '11 at 19:31
  • I know this is old but did no one notice that the namespace declaration is "xxforms" and does not match the namespace "xforms"? – Dave Williams Mar 13 '14 at 08:39

3 Answers3

16

try this

             "//fruit-name"

It shall find all fruitnames wherever they are in the document hierarchy.

Furqan Hameedi
  • 4,372
  • 3
  • 27
  • 34
  • 1
    @Furgan: Starting `//` operator isn't good practice when the schema is well known. –  Mar 03 '11 at 19:11
  • 2
    @Alejandro, that's a generalization that is not always correct. If an XPath implementation has an index of elements at its disposal (like the eXist database), writing `//fruit-name` will actually be faster! Also, running `//fruit-name` on a small instance like this probably won't make a difference. The reality is that which expression is "best" depends on a few factors. – ebruchez Mar 04 '11 at 19:18
  • @ebruchez: First, it's not a good practice. Second, I didn't say a full path would be always faster. But besides implementation optimizations, the problem is in the complexity: `descedant` axis will traverse the whole descedant tree even after finding a match. Also, the expression power of the language can easily break any optimization. Thinking in `(.)[$complex-condition]//element`. –  Mar 04 '11 at 20:20
  • 3
    @Alejandro: It's not enough to say something is not a good practice. There must be some rationale behind it. A good XPath optimizer working with an index does not need to traverse a tree, period. And if what you really want to express is "find every `fruit-name`" element in a document, then writing `//fruit-name` expresses exactly that. – ebruchez Mar 05 '11 at 08:49
4

If you want to select all the <fruit-name> from the instance instanceData (<xforms:instance id="instanceData">) that looks like the one you have in your question, the following should do it:

instance('instanceData')/fruits/fruit/fruit-name

If this doesn't work, one common reason is that you have a default namespace declaration in the document that contains your instance, like: xmlns="http://www.w3.org/1999/xhtml". If you have this, you need to undo that default namespace declaration on where you declare the instance, with:

<xforms:instance xmlns="" id="instanceData">

(And if this is the issue, my advice is not to use default namespace declarations. Ever. Instead declare xmlns:xhtml="http://www.w3.org/1999/xhtml" and use the xhtml prefix everywhere.)

ebruchez
  • 7,760
  • 6
  • 29
  • 41
avernet
  • 30,895
  • 44
  • 126
  • 163
  • i have edited my question with the correct view.xml. i did not use default namespace. but still it doesn't work. – Thangamani J Mar 07 '11 at 07:33
  • @Thangamani, if this doesn't work, I suspect this is due to the way you use that expression. See here a full example that shows all the fruits: https://gist.github.com/859678 – avernet Mar 08 '11 at 01:40
0

First: It may be a typo any way to point out you xml has wrong node ending

<service>

Second: your XPATH is very much valid but when you parse it out you need to iterate over the result set as like its a sequence of node and not a single value.

e.g) in JDOM :< Element.selectObject Vs selectSingleNodes Vs selectAsArray kind.

In your XForms you need to iterate over the resultset to get the list of fruits.

if you want only fruit names then you could try

instance('instanceData')/fruits/fruit/fruit-name/text()
kadalamittai
  • 2,076
  • 1
  • 16
  • 19