6

Please consider the following XML--

<div id="test">
    <p> Text sihdfaif</p>
    <p />
    <p> Text sihdfaif</p>
    <p />
    <p> Text sihdfaif</p>
    <p> Text sihdfaif</p>
    <p> Text sihdfaif</p>
</div>

Now, I want to obtain the number of p elements that have some text within them.. in this case, that value=5 (there are 2 'p' elements which are empty)

This is the XQuery that I came up with--

    let $claims_main := $doc//div[@id="test"]
        let $claims := $doc//div[@id="test"]/p
        let $n := count($claims)
        where $claims_main/p != '' 
        return $n

However the result that I get from the above is7, i.e. including the empty 'p' elements.

An alternative that I thought of, is using a for loop over all of the 'p' elements, but in that case how do I retrieve the total number of elements of the loop? If I use count in that case, then I simply get [1,1,1,1,1]- ie. count of each p element (since in the for loop the count would be for each of the 'p' elements, and not the div itself)...

Arvind
  • 6,404
  • 20
  • 94
  • 143

2 Answers2

10

As the question asks specifically for "p elements that have some text within them", here is how to get the number of precisely such p elements:

count(/*/div/p[string(.)])

This produces the number of all p elements with non-empty string value, that are children of a div that is a child of the top element of the XML document.

In addition, if "non-empty" also means having non white-space-only string value:

count(/*/div/p[normalize-space(.)])
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
1

Try this:

count($doc//div[@id='test']/p[node()])

the second predicate [node()] selects only elements that contain child nodes, it is equivalent to [./node()].

Leo Wörteler
  • 4,191
  • 13
  • 10