<p>I have an application which extracts data from an XML file using XPath. If a node in that XML source file is missing I want to return the value "N/A" (much like the Oracle NVL function). The trick is that the application doesn't support XSLT; I'd like to do this using XPath and XPath alone.</p>

<p>Is that possible?</p>

[{'answer_id': 40443, 'author': 'Hank Gay', 'author_id': 4203, 'author_profile': 'https://Stackoverflow.com/users/4203', 'pm_score': 2, 'selected': False, 'text': '<p>Short answer: no. Such a function was considered and explicitly rejected for version 2 of the XPath spec (see the non-normative <a href="http://www.w3.org/TR/xpath-functions/#examples" rel="nofollow noreferrer">Illustrative User-written Functions section</a>).</p>\n'}, {'answer_id': 41142, 'author': 'jelovirt', 'author_id': 2679, 'author_profile': 'https://Stackoverflow.com/users/2679', 'pm_score': 1, 'selected': False, 'text': '<p>It can be done with XPath 1.0. Say you have</p>\n\n<pre><code>&lt;foo&gt;\n  &lt;bar/&gt;\n&lt;/foo&gt;\n</code></pre>\n\n<p>If you want to test if <code>foo</code> has a <code>baz</code> child,</p>\n\n<pre><code>substring("N/A", 4 * number(boolean(/foo/baz)))\n</code></pre>\n\n<p>will return "N/A" if the expression <code>/foo/baz</code> returns an empty node-set, otherwise it returns an empty string.</p>\n'}, {'answer_id': 41152, 'author': 'jelovirt', 'author_id': 2679, 'author_profile': 'https://Stackoverflow.com/users/2679', 'pm_score': 4, 'selected': True, 'text': '<p>It can be done but only if the return value when the node does exist is <em>the string value of the node, not the node itself</em>. The XPath</p>\n\n<pre><code>substring(concat("N/A", /foo/baz), 4 * number(boolean(/foo/baz)))\n</code></pre>\n\n<p>will return the string value of the <code>baz</code> element if it exists, otherwise the string "N/A".</p>\n\n<p>To generalize the approach:</p>\n\n<pre><code>substring(concat($null-value, $node),\n          (string-length($null-value) + 1) * number(boolean($node)))\n</code></pre>\n\n<p>where <code>$null-value</code> is the null value string and <code>$node</code> the expression to select the node. Note that if <code>$node</code> evaluates to a node-set that contains more than one node, the string value of the <em>first</em> node is used.</p>\n'}, {'answer_id': 41713, 'author': 'JPLemme', 'author_id': 1019, 'author_profile': 'https://Stackoverflow.com/users/1019', 'pm_score': 1, 'selected': False, 'text': '<p>@jelovirt</p>\n\n<p>So if I understand this correctly, we concatenate the default answer and the value of the node, and then take the correct subset of the resulting string by testing for the existence of the node to set the offset to either zero or the position right after my default string. That is the most perverse twisting of a language I\'ve ever seen. (I love it!)</p>\n\n<p>To clarify what you said, this approach works when the the node is missing, not when the node is empty. But by replacing "number(boolean($node))" with "string-length($node)" it will work on empty nodes instead.</p>\n'}, {'answer_id': 43142, 'author': 'jelovirt', 'author_id': 2679, 'author_profile': 'https://Stackoverflow.com/users/2679', 'pm_score': 2, 'selected': False, 'text': '<p>For empty nodes, you need</p>\n\n<pre><code>boolean(string-length($node))\n</code></pre>\n\n<p>(You can omit the call to <code>number()</code> as the cast from boolean to number is implicit here.)</p>\n'}]
['https://Stackoverflow.com/questions/40361', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1019/']