Ruby 根据嵌套在wsdl:type中的模式验证XML文档
我有一些XML文件需要根据XSD进行验证,XSD嵌套在从web服务检索的WSDL文件中的Ruby 根据嵌套在wsdl:type中的模式验证XML文档,ruby,xml,xsd,nokogiri,xsd-validation,Ruby,Xml,Xsd,Nokogiri,Xsd Validation,我有一些XML文件需要根据XSD进行验证,XSD嵌套在从web服务检索的WSDL文件中的中 在内部有几个s。我正在使用ruby gemnokogiri加载XML文件并根据所述XSD验证它们,但是,当我运行程序时,我遇到以下错误: Element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope': No matching global declaration available for the validation root. 到目前为
中
在
内部有几个
s。我正在使用ruby gemnokogiri
加载XML文件并根据所述XSD验证它们,但是,当我运行程序时,我遇到以下错误:
Element '{http://schemas.xmlsoap.org/soap/envelope/}Envelope': No
matching global declaration available for the validation root.
到目前为止,我已经提取了
s(全部4个),并将它们复制到schema.xsd
文件中
代码:
require 'rubygems'
require 'nokogiri'
def validate(document_path, schema_path)
schema = Nokogiri::XML::Schema(File.read(schema_path))
document = Nokogiri::XML(File.read(document_path))
schema.validate(document)
end
validate('data.xml', 'schema.xsd').each do |error|
puts error.message
end
所以基本上我的schema.xsd
有多个
在那里,我不认为这本身就是一个问题,因为当我实例化schema
对象时,nokogiri
没有抛出错误
schema.xsd
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/">
<xs:element name="anyType" nillable="true" type="xs:anyType"/>
<xs:element name="anyURI" nillable="true" type="xs:anyURI"/>
<!-- data in here -->
</xs:schema>
<!-- three more xs:schema tags removed for brevity -->
data.xml
<?xml version='1.0' ?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header />
<env:Body>
<CreatePerson xmlns="https://person.example.com/">
<oMessageType xmlns:epa="http://schemas.datacontract.org/2004/07/whatever" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:array="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<person:bodyField>
<!-- data in here -->
</person:bodyField>
<!-- more data in here -->
</oMessageType>
</CreatePerson>
</env:Body>
</env:Envelope>
是的,WSDL不是XSD scheam,因此您需要手动或通过编程自动提取部分模式 这是示例代码,您需要重构它并在代码中使用
str = <<EOF
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="HelloService" targetNamespace="http://www.examples.com/wsdl/HelloService.wsdl">
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/">
<element name="anyType" nillable="true" type="anyType"/>
<element name="anyURI" nillable="true" type="anyURI"/>
<!-- data in here -->
</schema>
</types>
<message name="SayHelloRequest">
<part name="firstName" type="xsd:string"/>
</message>
<message name="SayHelloResponse">
<part name="greeting" type="xsd:string"/>
</message>
<portType name="Hello_PortType">
<operation name="sayHello">
<input message="tns:SayHelloRequest"/>
<output message="tns:SayHelloResponse"/>
</operation>
</portType>
<binding name="Hello_Binding" type="tns:Hello_PortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="sayHello">
<soap:operation soapAction="sayHello"/>
<input>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice"/>
</input>
<output>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice"/>
</output>
</operation>
</binding>
<service name="Hello_Service">
<documentation>WSDL File for HelloService</documentation>
<port name="Hello_Port" binding="tns:Hello_Binding">
<soap:address location="http://www.examples.com/SayHello/"/>
</port>
</service>
</definitions>
EOF
require 'rubygems'
require 'nokogiri'
doc = Nokogiri::XML(str)
doc.root.children.each do |child|
if child.node_name == 'types'
types = child
# p types.inner_html
xsd_doc = Nokogiri::XML(types.inner_html)
# p xsd_doc.root
xsd = Nokogiri::XML::Schema.from_document xsd_doc.root
end
end
str=我继续重构了我的代码,就像您在这里所做的那样,但我仍然得到了相同的错误消息:@hyde主要的想法是搜索嵌入的模式元素并创建一个新文档,然后您可以根据新文档创建xsd。就这样。我的示例代码是一个工作副本,但对于ProjectPropose,此代码并不漂亮,对于测试,您可以复制wsdl字符串来替换str
。对。这就是您的代码所做的——从WSDL中提取模式。但是,当我尝试使用提取的架构验证数据时,仍然会遇到相同的错误:元素“{}信封”:没有可用于验证根的匹配全局声明。假设您应该验证SOAP正文部分中的内容,因为您的架构是定义此xml,而不是定义整个信封。