0

Today I started learning libxml for the first time. And kept struggling to find the root node of the soap response. Damn struggled.

This is the xml buffer

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sti_xsd="http://www.openmobilealliance.org/schema/sti/v1_0" xsi:type="soapenv:Envelope">
    <soapenv:Body>
        <sti_xsd:TranscodingResponse>
            <sti_xsd:originatorID>test</sti_xsd:originatorID>
            <sti_xsd:operationID>1.0</sti_xsd:operationID>
            <sti_xsd:mainReturnResult>
                <sti_xsd:returnCode>2000</sti_xsd:returnCode>
                <sti_xsd:returnString>All 1 transcoding job(s) succeeded</sti_xsd:returnString>
            </sti_xsd:mainReturnResult>
            <sti_xsd:totalDuration>121</sti_xsd:totalDuration>
            <sti_xsd:jobResult>
                <sti_xsd:jobID>JOB26</sti_xsd:jobID>
                <sti_xsd:extensionData>
                    <sti_xsd:property>
                        <sti_xsd:name>van.sti.trx.MemoryUsage</sti_xsd:name>
                        <sti_xsd:value>3568808</sti_xsd:value>
                    </sti_xsd:property>
                </sti_xsd:extensionData>
                <sti_xsd:mainReturnResult>
                    <sti_xsd:returnCode>2000</sti_xsd:returnCode>
                    <sti_xsd:returnString>Successful TranscodingJob (200): Success</sti_xsd:returnString>
                </sti_xsd:mainReturnResult>
                <sti_xsd:duration>119</sti_xsd:duration>
                <sti_xsd:output>
                    <sti_xsd:contentType>application/vnd.wap.mms-message</sti_xsd:contentType>
                    <sti_xsd:contentTypeParams>
                        <sti_xsd:property>
                            <sti_xsd:name>type</sti_xsd:name>
                            <sti_xsd:value>application/smil</sti_xsd:value>
                        </sti_xsd:property>
                        <sti_xsd:property>
                            <sti_xsd:name>start</sti_xsd:name>
                            <sti_xsd:value>&lt;mms.smil&gt;</sti_xsd:value>
                        </sti_xsd:property>
                    </sti_xsd:contentTypeParams>
                    <sti_xsd:location>cid:133699816987026.JOB26</sti_xsd:location>
                    <sti_xsd:mediaSize>40693</sti_xsd:mediaSize>
                </sti_xsd:output>
            </sti_xsd:jobResult>
            <sti_xsd:extensionData>
                <sti_xsd:property>
                    <sti_xsd:name>van.sti.trx.session.id</sti_xsd:name>
                    <sti_xsd:value>STI/gesti05/120514_14h/STI17_23m12s214_00</sti_xsd:value>
                </sti_xsd:property>
                <sti_xsd:property>
                    <sti_xsd:name>van.sti.server.hostname</sti_xsd:name>
                    <sti_xsd:value>getrx01</sti_xsd:value>
                </sti_xsd:property>
            </sti_xsd:extensionData>
        </sti_xsd:TranscodingResponse>
    </soapenv:Body>
</soapenv:Envelope>

And below is my code:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

void parseStory ( xmlDocPtr doc, xmlNodePtr cur )
{

        xmlChar *key;
        cur = cur -> xmlChildrenNode;
        printf ( "Here\n" );
        while ( cur != NULL )
        {   
                if ( ( !xmlStrcmp ( cur -> name, ( const xmlChar * ) "returnCode" ) ) ) 
                {   
                        key = xmlNodeListGetString ( doc, cur -> xmlChildrenNode,1);
                        printf ( "keyword: %s\n", key );
                        xmlFree ( key );
                }   
                cur = cur -> next;
        }   
        return ;
}

static void parseDoc ( char *docname )
{
        xmlDocPtr doc;
        xmlNodePtr cur;
        doc = xmlParseFile ( docname );

        if ( doc == NULL )
        {   
                fprintf ( stderr, "Document not parsed successfully. \n" );
                return;
        }   
        printf ( "Parsing Successful\n" );
        cur = xmlDocGetRootElement ( doc );

        if ( cur == NULL )
        {   
                fprintf ( stderr, "empty document \n" );
                xmlFreeDoc ( doc );
                    printf ( "Got the root Node\n" );
        if ( xmlStrcmp ( cur->name, ( const xmlChar * ) "soapenv:Envelope" ) )
        {
                fprintf ( stderr, "Document of the wrong type root node != ");
                xmlFreeDoc(doc);
                return;

        }

        printf ( "Got the root \n" );
        cur = cur -> xmlChildrenNode;
        while ( cur != NULL )
        {
                if (cur->type == XML_ELEMENT_NODE) {

                                printf ( "Inside if  \n" );
                        if ( !(xmlStrcmp ( cur->name, ( const xmlChar * ) "mainReturnResult" ) ) )
                        {
                                printf ( "Inside \n" );
                                parseStory ( doc, cur );
                        }
                        cur = cur -> xmlChildrenNode;
                        continue;
                }
                cur = cur -> next;
        }

        xmlFreeDoc ( doc );
        return;
}

int main ( int argc, char **argv )
{
        char *docname;

        if ( argc <= 1 )
        {
                printf ( "Usage: %s docname\n", argv[0] );
                return ( 0 );
        }
        docname = argv [1];
        parseDoc ( docname );

        return ( 1 );
}
   return;

}

As stated I am struggling to find out the rootnode. Its saying "Document of the wrong type root node !=" Thanks.

reuben
  • 3,360
  • 23
  • 28
Nikhil
  • 576
  • 1
  • 11
  • 31

1 Answers1

2

The problem you're having is that "soapenv:Envelope" is not the name of the node. The name is simply "Envelope" in the namespace referred to by the "soapenv" alias.

Namespaces are what are confusing you here.

Addenda:

You already have the root node. You have it at the very beginning where you do:

cur = xmlDocGetRootElement ( doc );

The cur IS the root node.

If you immediately after do:

printf("Name = %s\n", cur->name);

You will see that you get "Envelope", which is correct.

Here is a simple example that dumps the Elements of your document. If you call it right after you assign cur you see that it basically dumps out your tree.

static void dumpNode (int indent, xmlNodePtr node) {
    while(node != NULL) {
        if (node->type == 1) {
            int i;
            for(i = 0; i < indent; i++) {
                printf("  ");
            }
            printf("%s : %s\n", node->ns->prefix, node->name);
        }
        dumpNode(indent + 1, node->children);
        node = node->next;
    }
}

Be aware that there are several "node types" within libxml, most notably are Type 1, which are elements, and Type 3, which is the text between elements. This code checks for Type 1 to print out the name and prefix. But also note it blindly calls dumpNode on the children, regardless of node type.

So, in the end, your root node will be a Type 1 element, with a name of Envelope (cur->name), a Namespace with an href of http://schemas.xmlsoap.org/soap/envelope/ (cur->ns->href), with a prefix of soapenv (cur->ns->prefix). The namespace prefix is NOT the namespace. You can not compare the prefixes of nodes and expect to be comparing the namespaces. The namespace is identified by, in this case, the href. The prefix is a shorthand, and can change from node to node, even for the same namespace (it tends not to, but it can, especially if you're importing other XML documents).

Will Hartung
  • 115,893
  • 19
  • 128
  • 203
  • okay. But, what will be the root node for this kind of xml buffer. How can i get root node? – Nikhil Jul 08 '12 at 14:32