Reputation: 4551
I have an input XML something on this line:
<Holding id="12">
<Policy>
<HoldingForm tc="1">Individual</HoldingForm>
<PolNumber>848433</PolNumber>
<LineOfBusiness tc="1">Life</LineOfBusiness>
<CarrierCode>67644</CarrierCode>
</Policy>
</Holding>
My manipulation on this XML depends on if <PolNumber>
(its an optional element in schema) has a value or not. I'm using Mule 3.3 xpath
evaluator to do this and my XPath expression looks this:
<expression-filter expression="#[xpath('//acord:Holding/acord:Policy/acord:PolNumber').text != empty]"/>
This works fine as long as <PolNumber>
element is present or <PolNumber/>
is empty element. But if <PolNumber>
is absent, above expression throws exception.
I tried using XPath boolean function but it returns true
for <PolNumber/>
. Is there a better way of checking if an element is present and non-empty?
EDIT:
This is the configuration of namespace manager in my mule config
<xm:namespace-manager includeConfigNamespaces="true">
<xm:namespace prefix="acord" uri="http://ACORD.org/Standards/Life/2" />
<xm:namespace prefix="soap" uri="http://schemas.xmlsoap.org/soap/encoding/" />
</xm:namespace-manager>
Upvotes: 22
Views: 82891
Reputation: 697
Maybe I'm a bit late here, but answers are a bit confusing. This one will always returns false when text is blank or with spaces but no chars.
boolean//Holding/Policy/PolNumber/child/text()[normalize-space()]
Upvotes: 3
Reputation: 61
How about expression="#[?xpath('//acord:Holding/acord:Policy/acord:PolNumber').text != empty]"
? This should work in in all situations
Upvotes: 2
Reputation: 243459
Use:
boolean(//acord:Holding/acord:Policy/acord:PolNumber/text()[1])
this produces true()
if //acord:Holding/acord:Policy/acord:PolNumber
has a first text-node child, and false()
otherwise.
Do note: This is more efficient than counting all text-node children just to compare the count with 0.
Upvotes: 31
Reputation: 38662
You can use boolean(...)
for checking if it's empty, but make sure to look inside the element.
boolean(//PolNumber/node())
This also works if other nodes are contained. If you want to limit to text nodes, replace node()
by text()
. You could want to use //text()
instead, then the query will also yield true for text nodes inside other child elements of <PolNumber/>
.
Upvotes: 13
Reputation: 33413
What about using count
to get the number of text nodes:
<expression-filter
expression="#[xpath('count(//Holding/Policy/PolNumber/child::text())') != 0]"/>
Upvotes: 2