xmlcocoasoapxsdcisco-axl

Soap xml response validate with xsd file


using https://www.freeformatter.com/xml-validator-xsd.html

If i take soapenf completely out of the mix here in the response and the schema, it works fine, but would like to do both.

(fyi i would like to point out this wsdl and xsd is not exposed on the endpoint, CISCO provides the zip file of the wsdl an xsd file) You then can send requests to the server per the wsdl/xsd and it will work. But the wsdl and xsd are not available on the cisco.com or the vm or domain you have the service installed)

This works perfectly in c# if i point to files, but i would like to load the xml document into NSXMLDocument variable document and have it point to its own schemaFile and just call validate

I have the following soap xml

<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Body>
<ns:getCCMVersionResponse xmlns:ns="http://www.cisco.com/AXL/API/10.5"><return><componentVersion>     
<version>10.5.2.11900(3)</version>
</componentVersion>
</return>
</ns:getCCMVersionResponse>
</soapenv:Body>
</soapenv:Envelope>

I took the bare minimum out of the xsd file that was provided by cisco and the online tool works with

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:axlapi="http://www.cisco.com/AXL/API/10.5" 
attributeFormDefault="unqualified" elementFormDefault="unqualified" 
targetNamespace="http://www.cisco.com/AXL/API/10.5" version="10.5">
 <xsd:import namespace="http://schemas.xmlsoap.org/soap/envelope/" schemaLocation="http://schemas.xmlsoap.org/soap/envelope/"/>
  <xsd:complexType name="GetCCMVersionRes">
    <xsd:complexContent>
        <xsd:extension base="axlapi:APIResponse">
            <xsd:sequence>
                <xsd:element name="return">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="componentVersion">
                                <xsd:complexType>
                                    <xsd:sequence>
                                        <xsd:element name="version" type="axlapi:String50"/>
                                    </xsd:sequence>
                                </xsd:complexType>
                            </xsd:element>
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
            </xsd:sequence>
        </xsd:extension>
    </xsd:complexContent>
</xsd:complexType>
<xsd:element name="getCCMVersionResponse" type="axlapi:GetCCMVersionRes"/>
    <xsd:simpleType name="String50">
    <xsd:restriction base="xsd:string">
        <xsd:maxLength value="50"/>
    </xsd:restriction>
</xsd:simpleType>
<xsd:complexType abstract="true" name="APIResponse">
    <xsd:annotation>
        <xsd:documentation>All responses must extend abstractResponse.</xsd:documentation>
    </xsd:annotation>
    <xsd:attribute name="sequence" type="xsd:unsignedLong" use="optional"/>
</xsd:complexType>
</xsd:schema>

Please note i had to add below to the xsd file for it to get past a SOAP error

<xsd:import namespace="http://schemas.xmlsoap.org/soap/envelope/" schemaLocation="http://schemas.xmlsoap.org/soap/envelope/"/>

And it works in the online tool

Now this is great and all for an online tool, but i would like to verify the document itself. This is done (if you read the online tool), by adding to the Soap request envelope element "noNamespaceSchemaLocation" or "schemaLocation" and a http path to the xsd file (or the partial file i created above)

I have tried all sorts of ways using the online tool, and it would never validate. its currently hosted at http://test123a.epizy.com/getCCMVersion.xsd (i hope its not because its a free host that im having a problem), but there should also be ways to accomplish this using file:///

I am using macOS, and objective-c, but all the code is doing, is manipulating the soap xml response header, and putting the location of file:///. I have also tried http:// as well.

Can anyone solve this absolute mystery? It seems so plain and simple from some of the examples online....

Validate XML Schema with xsd file in Cocoa?

http://answerqueen.com/2j/q7vz0zv32j

How to fix soapenv:Envelope issue in XSD schema while validating with SOAP request/response

https://code.i-harness.com/en/q/8bfd7

How to reference a local XML Schema file correctly?

Cvc-elt.1: Cannot Find The Declaration Of Element 'soap:Envelope'

Thank you for your help in advance

this guy never got an answer SOAP Response Schema Validation


Solution

  • Turns out you can only validate one or the other. You cannot load the soap response and validate the soap, and the xml inside it all in one call. You can separate the soap, and the xml and validate the separately.

    Here is the correct code to do so

    <?xml version='1.0' encoding='UTF-8'?>"
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/soap/envelope/ http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
    <ns:getCCMVersionResponse xmlns:ns="http://www.cisco.com/AXL/API/10.5"                                                       
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                                              
    xsi:schemaLocation="http://www.cisco.com/AXL/API/10.5  
    /Users/michael/Downloads/axlsqltoolkit/schema/current/getCCMVersion.xsd">
    <return>
    <componentVersion>
    <version>10.5.2.11900(3)</version>
    </componentVersion>
    </return>
    </ns:getCCMVersionResponse>
    </soapenv:Body>
    

    You cannot validate the SOAP and the XML inside at the same time. You will have to use xpath to get to xml and can validate, as validating soap is not as important.

    What was interesting is in the xml

    I could not use xsi:noNameSpaceSchemaLocation="file:///Users/michael/Downloads/axlsqltoolkit/schema/current/getCCMVersion.xsd">

    as in the xml xsi:schemaLocation="http://www.cisco.com/AXL/API/10.5
    /Users/michael/Downloads/axlsqltoolkit/schema/current/getCCMVersion.xsd"> is already referenced as a schema namespace

    So the alternative had to be used above.

    Also, I had to edit the schema file to fix some namespace issues, per the xml response xmlns:ns="http://www.cisco.com/AXL/API/10.5", ns is the namespace,

    But in the schema file, it is references as axlapi , all references where changed to ns

    Hopefully this will help somebody in the future. FYI, pointing the the entire AXLSoap.xsd file for validation took a few minutes, and had to be abandoned

    Turns out you can only validate one or the other. You cannot load the soap response and validate the soap, and the xml inside it all in one call. You can separate the soap, and the xml and validate the separately.

    Here is the correct code to do so

    <?xml version='1.0' encoding='UTF-8'?>"
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/soap/envelope/ http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
    <ns:getCCMVersionResponse xmlns:ns="http://www.cisco.com/AXL/API/10.5"                                                       
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                                              
    xsi:schemaLocation="http://www.cisco.com/AXL/API/10.5  
    /Users/michael/Downloads/axlsqltoolkit/schema/current/getCCMVersion.xsd">
    <return>
    <componentVersion>
    <version>10.5.2.11900(3)</version>
    </componentVersion>
    </return>
    </ns:getCCMVersionResponse>
    </soapenv:Body>
    

    You cannot validate the SOAP and the XML inside at the same time. You will have to use xpath to get to xml and can validate, as validating soap is not as important.

    What was interesting is in the xml

    I could not use xsi:noNameSpaceSchemaLocation="file:///Users/michael/Downloads/axlsqltoolkit/schema/current/getCCMVersion.xsd">

    as in the xml xsi:schemaLocation="http://www.cisco.com/AXL/API/10.5
    /Users/michael/Downloads/axlsqltoolkit/schema/current/getCCMVersion.xsd"> is already referenced as a schema namespace

    So the alternative had to be used above.

    Also, I had to edit the schema file to fix some namespace issues, per the xml response xmlns:ns="http://www.cisco.com/AXL/API/10.5", ns is the namespace,

    But in the schema file, it is references as axlapi , all references where changed to ns

    Hopefully this will help somebody in the future. FYI, pointing the the entire AXLSoap.xsd file for validation took a few minutes, and had to be abandoned

    The final objective-c NSXMLDocument function, to handle either validating the soap or the xml is here.

        BOOL validateDocumentUsingXMLSchemaAtPath( NSXMLDocument *doc, 
    NSString* xsdPath, NSString *schemaNameSpace )
    {
        BOOL validationResult = NO;  // Default to failing validation.
    
        // Get the root of the document.
        NSXMLElement *rootElement = [doc rootElement];
    
        // Add the XMLSchema-instance namespace, if it doesn't already exist
        NSXMLNode *namespace = [NSXMLNode namespaceWithName:@"xsi"
                                            stringValue:@"http://www.w3.org/2001/XMLSchema-instance"];
        [rootElement addNamespace:namespace];
    
        // Add the No Namespace Schema Location attribute referencing the local XSD file, and associate the XML Schema for validation.
        NSURL *xsdURL = [NSURL fileURLWithPath:xsdPath];
    
        NSString *schemaLocation = nil;
        if ( namespace == nil )
        {
            schemaLocation = @"noNamespaceSchemaLocation";
            schemaNameSpace = @"";
        }
        else
        {
            schemaLocation = @"schemaLocation";
        }
    
        NSString *schemaSpace = [NSString stringWithFormat:@"%@%@%@", schemaNameSpace, ([schemaNameSpace length] > 0) ? @" " : @"", [xsdURL description]];
    
    NSXMLNode *schemaAttribute = [NSXMLNode attributeWithName:[NSString stringWithFormat:@"xsi:%@", schemaLocation]
                                                        stringValue:schemaSpace];
        [rootElement addAttribute:schemaAttribute];
    
        // Validate the document
        NSError *error = nil;
        validationResult = [doc validateAndReturnError:&error];
    
        if ( !validationResult )
             NSLog( @" %@", [error localizedDescription] );
    
        return validationResult;
        }
    
    
    //usage
    //find your soap, or xml document and put it in xmlDoc
                   BOOL ret = validateDocumentUsingXMLSchemaAtPath(xmlDoc,xsdURL, @"http://www.cisco.com/AXL/API/10.5");