1

I have to parse oprResult/@code from below XML using XPath. The XPath expression

//*[local-name()='oprResult']/@code

is working as expected, BUT I could not use name or local-name functions as '(' ')' are used as delimiter in my parsing function.

Is it possible to parse oprResult without local-name?

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <ChangeResponse xmlns="http://www.example.com" code="0" message="Success">
            <oprResult code="0" message="Success"/>
        </ChangeResponse>
    </soap:Body>
</soap:Envelope>
5
  • 1
    You don't have to use predicates (expressions in square brackets) to select elements. Simply specify a path: //oprResult/@code. A proper solution would be to fix your "parsing function" to not use parentheses as delimiters. Commented Oct 13, 2014 at 7:35
  • 5
    local-name is necessary when you're trying to ignore namespaces (stackoverflow.com/questions/4402310/…). If that's the case here, use the correct namespace instead. Commented Oct 13, 2014 at 8:33
  • //oprResult/@code didn't worked in my case. parsing function change may affect whole system as there are a no of xpath mapped already for different results. There may be many side effects. Unfortunately there is no namespace given for <ChangeResponse xmlns="example.com" code="0" message="Success"> so using namespace is also not possible in this case Commented Oct 13, 2014 at 9:35
  • 2
    What environment do you use XPath in? Java? There is a namespace defined for ChangeResponse, just not with a prefix, since it is a default namespace. But the prefix is irrelevant - depending on the environment you could perhaps register that namespace before applying the XPath expression. Commented Oct 13, 2014 at 12:20
  • Oh, and in case I was not clear on this, what I meant was: Show more code, not just the path expression in isolation. Commented Oct 13, 2014 at 12:21

1 Answer 1

4

Is it possible to parse oprResult without local-name?

Yes*

Not only is it possible to select an XML element without using local-name(), it is actually preferred.

One common reason you see example XPaths with constructs such as

//*[local-name()='oprResult']

is that namespace declarations are not an intrinsic part of XPath; namespace and namespace prefix declarations occur in the greater context of the system or language using an XPath library.

If you cannot make your system tolerate the parentheses of local-name(), if //oprResult/@code doesn't suite, or if you are simply interested in using namespaces properly rather than defeating them, figure out how to declare a namespace prefix, say ex: for the http://www.example.com namespace, and use the namespace prefix in the XPath. Read on for how...

You do not say what the language and/or library you're using for XPath, but here are a few examples to give a feel for what to look for...

XSLT:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:ex="http://www.example.com">
   ...

Python (LibXML):

my $xc = XML::LibXML::XPathContext->new($xhtml_doc);
$xc->registerNs('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
$xc->registerNs('ex', 'http://www.example.com');

Javas (SAX):

NamespaceSupport support = new NamespaceSupport();
support.pushContext();
support.declarePrefix("soap", "http://schemas.xmlsoap.org/soap/envelope/");
support.declarePrefix("ex", "http://www.example.com");

Once you've declared namespace prefixes, your XPath can be:

/soap:Envelope/soap:Body/ex:ChangeResponse/oprResult/@code

* ...but the reason should not be to avoid parentheses because they "are used as delimiters in a parsing function." First of all, if an XPath parser is having trouble with embedded parens, get a new XPath parser; if a tool that uses an XPath library is preventing you from using parens, get a new tool (or investigate deeper to be sure the tool is not being used as well as it can be). Secondly, as @predi observed in the question comments, if there's only a single oprResult element and your response is small enough that you don't mind the inefficiency, in your case you can use an XPath without namespaces: //oprResult/@code

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.