Pradeep0308
asked on
Xpath Assistance
Hi,
I have a SOAP response received as below:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode>s:Server</fault code>
<faultstring>Fatura ID sistemde mevcut</faultstring>
<detail>
<ProcessingFault xmlns="http:/abcde.com/eInvoice/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Code>3012</Code>
<Message>ABCDE</Message>
</ProcessingFault>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
I want to check the existence of the element Code or Message using string-length and if it is greater than zero. How can I achieve that using the Xpath.
Regards
Pradeep
I have a SOAP response received as below:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode>s:Server</fault
<faultstring>Fatura ID sistemde mevcut</faultstring>
<detail>
<ProcessingFault xmlns="http:/abcde.com/eInvoice/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Code>3012</Code>
<Message>ABCDE</Message>
</ProcessingFault>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
I want to check the existence of the element Code or Message using string-length and if it is greater than zero. How can I achieve that using the Xpath.
Regards
Pradeep
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Note that a node-set in a boolean expression returns false() when empty,
so in an XSLT you would do
<xsl:if test="//*[local-name() = 'Code'][normalize-space(.) ] | //*[local-name() = 'Message'][normalize-space (.)] ">...
so in an XSLT you would do
<xsl:if test="//*[local-name() = 'Code'][normalize-space(.)
And XPath1.0 and you would be able to use a namespace manager
//abc:Code[normalize-space (.)] | //abc:Message[normalize-sp ace(.)]
just make sure you bind prefix abc: to this namespace in the namespacemanager "http:/abcde.com/eInvoice/"
//abc:Code[normalize-space
just make sure you bind prefix abc: to this namespace in the namespacemanager "http:/abcde.com/eInvoice/"
ASKER
Hi Geert,
I can use Xpath 2.0 If you are suggesting not to use string-length than how should I check the existence of either of these two elements and then do a certain step?
Regards
Pradeep
I can use Xpath 2.0 If you are suggesting not to use string-length than how should I check the existence of either of these two elements and then do a certain step?
Regards
Pradeep
By string casting
//*:Code[string(.)]
or
//*:Code[normalize-space(. )]
both string() and normalize-space() cast the node to string
the [] requires a boolean expression inside
casting a string to a boolean expression returns true() if the string length is > 0
//*:Code[string(.)]
will only return true() if there is a Code element in the envelope that has a stringvalue other than the empty string
//*:Code[string(.)]
or
//*:Code[normalize-space(.
both string() and normalize-space() cast the node to string
the [] requires a boolean expression inside
casting a string to a boolean expression returns true() if the string length is > 0
//*:Code[string(.)]
will only return true() if there is a Code element in the envelope that has a stringvalue other than the empty string
ASKER
Thanks Geert. Will this return true() or only true?
//*:Code[string(.)]
will return the node-set of all the *:Code elements that have non zero content
If you use //*:Code[string(.)] in a test (anywhere Xpath expects a boolean expression, example: inside the test attribute of an if statement in XSLT, inside an if() or inside the predicate [], ...)
then it will return an xs:boolean
true() when the node-set is not empty
false() when the node-set is empty
that is because of the casting rules from node-set to boolean
will return the node-set of all the *:Code elements that have non zero content
If you use //*:Code[string(.)] in a test (anywhere Xpath expects a boolean expression, example: inside the test attribute of an if statement in XSLT, inside an if() or inside the predicate [], ...)
then it will return an xs:boolean
true() when the node-set is not empty
false() when the node-set is empty
that is because of the casting rules from node-set to boolean
ASKER
ok so what happens if I do CodeTest=//*:Code[string(. )]
Will CodeTest have the value as xs:boolean i.e. true()?
Will CodeTest have the value as xs:boolean i.e. true()?
no, it will contain the nodeset
but you can force the boolean cast
CodeTest=boolean(//*:Code[ string(.)] )
be carefull not to cast to boolean prematurely
if you have this
CodeTest=//*:Code[string(. )]
and you remember that Codetest is a nodeset, not a boolean,
it will cast to boolean more efficiently when you use it in a test
but you can force the boolean cast
CodeTest=boolean(//*:Code[
be carefull not to cast to boolean prematurely
if you have this
CodeTest=//*:Code[string(.
and you remember that Codetest is a nodeset, not a boolean,
it will cast to boolean more efficiently when you use it in a test
ASKER
Thanks Geert. Do you provide any freelance consulting on XML and related technologies? Like Xpath and XSLT?
Regards
Pradeep
Regards
Pradeep
Hi Pradeep,
Yes I do, I am a full time XML/XSLT freelance consultant.
If you want to contact me, you can push the "hire me" button or find my email adress on my profile page
Yes I do, I am a full time XML/XSLT freelance consultant.
If you want to contact me, you can push the "hire me" button or find my email adress on my profile page
//*[local-name() = 'Code'][normalize-space(.)