tags:

views:

37

answers:

5

I have an XML file:

$xml := <xml>
          <element>
              <text>blahblah</text>
          </element>
          <element>
          </element>
          <element>
              <text>blahblah</text>
          </element>
      </xml>

I can use the query

for $x in $xml/xml/element/text return string($x)

This gives me a list

blahblah
blahblah

with no indication that there is an element which has no element. What I'd like to do is use a query which, if there is no such element, returns, say "missing". How do I do this?

A: 

This should work:

for $x in $xml/xml/element
return
  if (text)
  then string(text)
  else "missing"
Oliver Hallam
A: 

For a sequence of strings (slightly modified version of the first answer):

for $e in $xml/xml/element
return
  if ($e/text)
  then string($e/text)
  else "missing"

or using a let (which seems a little cleaner to me... but it's probably just 6 of one and half dozen of the other):

for $e in $xml/xml/element
let $text := string($e/text)
return
  if ($text)
  then $text
  else "missing"

Hope that helps.

ksclarke
+1  A: 

Are you trying to return the "element" elements that don't have any children? (In your example, it's the second occurrence of "element" as the first and last contain "text" elements.)

If so, you can use a predicate in an XPath expression:

/xml/element[not(child::*)]
DevNull
A: 

in MarkLogic


for $e in $xml/xml/element
   return ($e/text,"missing")

kadalamittai
A: 

$xml/element/string((text,"missing")[1])

  • functions are allowed in XPath expressions, so an explicit loop is not needed here.

  • the expression (text,"missing")[1]

returns the first non-null item in the sequence of the text element followed by the string "missing"

  • you can use the eXist sandbox to execute code snippets:-

http://demo.exist-db.org/exist/sandbox/sandbox.xql

Chris Wallace