4

I am making an iOS app where I'm using the GDataXML library for xml parsing in Objective C.

I have the following xml (that I get as an soap response):

<?xml version="1.0" encoding="utf-8"?>
  <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
      <MakeRequestResponse xmlns="http://tempuri.org/">
        <MakeRequestResult>SOMERANDOMDATAHERE012912033905345346</MakeRequestResult>
      </MakeRequestResponse>
    </soap:Body>
  </soap:Envelope>

The problem I have is:

when I write the xpath expression for the given xml like this I get the MakeRequestResponse node:

NSArray *listOfNodes = [[responseDocument rootElement] nodesForXPath:@"soap:Body/*" error:&error];

However I'm unable to get this node or any children below when I write the actual node name:

NSArray *listOfNodes = [[responseDocument rootElement] nodesForXPath:@"soap:Body/MakeRequestResponse" error:&error];

I'm not sure what is the issue here. Could it be an namespace related issue?

lgdev
  • 244
  • 1
  • 11

1 Answers1

8

This is a FAQ (search for XPath and default namespace).

The short answer is that when an XPath expression is evaluated, any unprefixed names are assumed to be in "no namespace". But MakeRequestResponse is not in "no namespace" and thus isn't selected.

Solution:

Either register the "http://tempuri.org/" namespace and associate a prefix (say "x:") to it, then use:

soap:Body/x:MakeRequestResponse

Or, otherwise you can have an expression like this:

soap:Body/*[name() = 'MakeRequestResponse']
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • As I see, the "issue" is actually in the xml document itself. The right way of doing it would be to change the xml. The other one is working, but it seems a bit of a quirk. Thanks – lgdev Nov 15 '11 at 15:52
  • @Luka - I'm a little late here, but, no, the error is not "*actually in the xml document itself*". Re-read Dimitre's solution. – Wayne Dec 01 '11 at 22:45
  • @_Luka: @lwburk is completely right -- it is OK (not a problem) for XML documents or fragments to be in a default namespace. – Dimitre Novatchev Dec 01 '11 at 23:49
  • @DimitreNovatchev: I agree that it is ok for the xml documents to be in a default namespace. However, as you've explained the 'MakeRequestResponse' element in my example is neither in a default no-namespace (because it has an xmlns attribute which defines an custom namespace) neither it is in a accessible namespace (because it does not have an prefix associated with the xmlns attribute). From what I've seen on this site, some other xml libraries treat cases like mine as a no-namespace elements, since the definition (xmlns) without a prefix is not correct. Correct me if I'm wrong. – lgdev Dec 02 '11 at 09:20
  • @Luka: These "some other xml libraries" are clearly non-compliant and it is a good idea to avoid them. Re-defining the default namespace at any element in the XML document is a standard feature of XML Namespaces. From the W3C spec (http://www.w3.org/TR/REC-xml-names/#defaulting): "*default namespace declaration extends from the beginning of the start-tag in which it appears to the end of the corresponding end-tag, excluding the scope of any inner default namespace declarations. In the case of an empty tag, the scope is the tag itself*." – Dimitre Novatchev Dec 02 '11 at 13:27
  • I was banging my head against this problem for hours. Thanks very much for the solution. – Joshua Smith Jan 13 '12 at 18:01