肥皂XML响应使用XSD文件进行验证

时间:2018-07-06 19:34:40

标签: xml cocoa soap xsd cisco-axl

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

如果我在响应和模式中完全不使用soapenf,那么它可以正常工作,但同时希望两者兼具。

(仅供参考,此wsdl和xsd不在端点上公开,CISCO为wsdl的zip文件提供一个xsd文件),然后可以根据wsdl / xsd向服务器发送请求,它将工作。但是wsdl和xsd在cisco.com或您已安装服务的vm或域上不可用)

如果我指向文件,这在c#中效果很好,但是我想将xml文档加载到NSXMLDocument变量文档中,并使其指向自己的schemaFile,然后调用validate

我有以下肥皂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>

我从cisco提供的xsd文件中删除了最低限度,并且可以使用在线工具

<?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>

请注意,为了克服SOAP错误,我必须在xsd文件中添加以下内容

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

它可以在在线工具中使用

现在这很好,并且对于在线工具都是如此,但是我想验证文档本身。通过在Soap请求信封元素中添加“ noNamespaceSchemaLocation”或“ schemaLocation”以及xsd文件(或我在上面创建的部分文件)的http路径来完成此操作(如果您阅读在线工具)

我已经使用在线工具尝试了各种方式,但是它永远不会得到验证。它目前托管在http://test123a.epizy.com/getCCMVersion.xsd(我希望不是因为它是一个有问题的免费主机),但也应该有一些方法可以使用file:///

我正在使用macOS和Objective-c,但是所有代码都在做,正在操作soap xml响应标头,并放置file:///的位置。我也尝试过http://。

有人能解决这个绝对的谜吗?从某些在线示例看来,它是如此简单明了。...

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'

谢谢您的帮助

此人从未得到答案SOAP Response Schema Validation

1 个答案:

答案 0 :(得分:1)

原来,您只能验证一个或另一个。您无法在一次调用中加载Soap响应并验证Soap及其内部的xml。您可以将soap和xml分开,并分别进行验证。

这是正确的代码

<?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>

您不能同时验证内部的SOAP和XML。您将必须使用xpath进入xml并可以进行验证,因为验证soap并不那么重要。

有趣的是xml

我无法使用xsi:noNameSpaceSchemaLocation =“ file:///Users/michael/Downloads/axlsqltoolkit/schema/current/getCCMVersion.xsd”>

如xml xsi:schemaLocation =“ http://www.cisco.com/AXL/API/10.5
    /Users/michael/Downloads/axlsqltoolkit/schema/current/getCCMVersion.xsd“>已被引用为架构命名空间

所以必须在上面使用替代方法。

此外,我必须编辑架构文件以解决一些名称空间问题,根据xml响应xmlns:ns =“ http://www.cisco.com/AXL/API/10.5”,ns是名称空间,< / p>

但是在模式文件中,它的引用为axlapi,所有引用都更改为ns

希望这会在将来对某人有所帮助。仅供参考,将整个AXLSoap.xsd文件指向进行验证需要花费几分钟,因此必须放弃

原来,您只能验证一个或另一个。您无法在一次调用中加载Soap响应并验证Soap及其内部的xml。您可以将soap和xml分开,并分别进行验证。

这是正确的代码

<?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>

您不能同时验证内部的SOAP和XML。您将必须使用xpath进入xml并可以进行验证,因为验证soap并不那么重要。

有趣的是xml

我无法使用xsi:noNameSpaceSchemaLocation =“ file:///Users/michael/Downloads/axlsqltoolkit/schema/current/getCCMVersion.xsd”>

如xml xsi:schemaLocation =“ http://www.cisco.com/AXL/API/10.5
    /Users/michael/Downloads/axlsqltoolkit/schema/current/getCCMVersion.xsd“>已被引用为架构命名空间

所以必须在上面使用替代方法。

此外,我必须编辑架构文件以解决一些名称空间问题,根据xml响应xmlns:ns =“ http://www.cisco.com/AXL/API/10.5”,ns是名称空间,< / p>

但是在模式文件中,它的引用为axlapi,所有引用都更改为ns

希望这会在将来对某人有所帮助。仅供参考,将整个AXLSoap.xsd文件指向进行验证需要花费几分钟,因此必须放弃

最终的Objective-c NSXMLDocument函数,用于处理肥皂或xml验证。

    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");