SOAP响应模式验证 短版:
我正在尝试编写一个XSD来验证SOAP服务的响应。我觉得有必要只导入http://schemas.xmlsoap.org/soap/envelope/,而不是重新定义信封、头和正文等soap元素,但正文的xmlsoap.org模式定义对我来说太宽泛了——一旦导入soap模式,我的XSD(我为我的服务精心定制的)就会验证所有soap消息 我应该如何处理XSD中SOAP信封、头部和主体的定义? 我怀疑问题在于我正在尝试重用其他不应该重用的模式。当然,这些SOAP模式旨在定义(所有)SOAP消息的外观。也许我只需要在我的模式中定义我想要的特定soap主体的样子 我可能刚刚回答了我自己的问题。也许有人有不同的解决方案 长版本: 我在编写XSD来描述来自我的一个SOAP服务的响应消息时遇到了一些问题 下面是我正在尝试验证的来自我的服务的响应示例:SOAP响应模式验证 短版:,soap,xsd,schema,validation,Soap,Xsd,Schema,Validation,我正在尝试编写一个XSD来验证SOAP服务的响应。我觉得有必要只导入http://schemas.xmlsoap.org/soap/envelope/,而不是重新定义信封、头和正文等soap元素,但正文的xmlsoap.org模式定义对我来说太宽泛了——一旦导入soap模式,我的XSD(我为我的服务精心定制的)就会验证所有soap消息 我应该如何处理XSD中SOAP信封、头部和主体的定义? 我怀疑问题在于我正在尝试重用其他不应该重用的模式。当然,这些SOAP模式旨在定义(所有)SOAP消息的外观
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<helloResponse xmlns="http://justinfaulkner/wsdl/1.0">
<Message>Hello, Justin!</Message>
<Message>Your lucky numbers are: 329, 9</Message>
</helloResponse>
</soap:Body>
</soap:Envelope>
你好,贾斯汀!
你的幸运数字是:329,9
我的目标是使用XSD验证来自我的服务的响应。
因此,我手工编写了一个XSD,它描述了属于我的服务的soap:Body中的所有类型
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://justinfaulkner/wsdl/1.0" xmlns:tns="http://justinfaulkner/wsdl/1.0">
<xsd:complexType name="helloResponseType">
<xsd:sequence>
<xsd:element name="Message" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="helloResponse" type="tns:helloResponseType"/>
</xsd:schema>
当我尝试使用PHP的DOMDocument::schemaValidateSource()功能用模式(第二个片段)验证示例响应(第一个XML片段)时,验证程序指出了我的第一个明显错误:
元素“soap:Envelope”:没有匹配的全局声明可用
“哦,没错,”我想,“这些元素是在SOAP的命名空间中定义的,所以我需要导入SOAP的XSD。”
因此,我编辑了我的XSD并添加了一个导入:
<xsd:import namespace="http://schemas.xmlsoap.org/soap/envelope/" schemaLocation="http://schemas.xmlsoap.org/soap/envelope/"/>
成功了!当我用XSD验证soap响应时,schemaValidateSource返回true
然后,作为一项理智检查,我使用了一个不同的soap响应XSD,它是我所使用的:
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://justinfaulkner/wsdl/1.0" xmlns:tns="http://justinfaulkner/wsdl/1.0">
<xsd:import namespace="http://schemas.xmlsoap.org/soap/envelope/" schemaLocation="http://schemas.xmlsoap.org/soap/envelope/"/>
<xsd:complexType name="OtherServiceResponseType">
<xsd:all>
<xsd:element name="CompletionCode" type="xsd:string"/>
<xsd:element name="ResponseMessage" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
<xsd:element name="OtherServiceResponse" type="tns:OtherServiceResponseType"/>
</xsd:schema>
我试图用这个完全不相关的模式验证我的soap响应
而乍一看根本不描述此消息的模式也验证了soap响应。
然后我意识到XSD的模式必须是响应针对这两个不同模式进行验证的原因。我从中导入的SOAP架构将Body元素定义为:
<xs:element name="Body" type="tns:Body" />
<xs:complexType name="Body" >
<xs:sequence>
<xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##any" processContents="lax" >
<xs:annotation>
<xs:documentation>
Prose in the spec does not specify that attributes are allowed on the Body element
</xs:documentation>
</xs:annotation>
</xs:anyAttribute>
</xs:complexType>
规范中的散文没有指定允许在Body元素上使用属性
这允许Body标签的内容基本上是任何内容
这是有道理的,XSD的XSD的目的是定义所有XSD的外观,而不仅仅是我的
所以我的问题是,我应该如何构建一个XSD来验证这些SOAP响应,如果可能的话重用现有的SOAP XSD?
这是我一直追求的方向
- 我想我可以把xmlsoap.org的XSD模式扔出窗口,自己重新定义信封和主体,精确地指定主体元素中应该显示的内容。但我觉得我最终基本上会在我自己的XSD中拥有所有soap元素的副本,头部和身体的定义略有不同,这感觉像是违反了DRY
- 有没有一种方法可以导入xmlsoap.org的XSD,然后从XSD中重写soap:Body的定义