我的情况类似于“XSD with elements from other namespace”,其中我有2个XML。
一个XML版本充当另一个的包装器。在一个简单的例子中 - 我们有一个MESSAGES包装器,至少包含一个MESSAGE元素。每个MESSAGE元素都包含一个PAYLOAD,它根据XSD进行验证。
给定MESSAGES父级中的每个PAYLOAD将针对相同的XSD进行验证。但是,不同的MESSAGES可以包含针对整个XSD进行验证的PAYLOAD。我确实有数百个XSD来验证不同类型的PAYLOAD。
我希望拥有自己的XSD来验证MESSAGES包装器的结构,然后根据PAYLOAD类型,将PAYLOAD验证到我拥有的许多库存XSD之一的负责人。
重要的是我们无法将PAYLOAD XSD导入MESSAGE XSD - 因为PAYLOAD模式类型未在XSD级别修复。但它固定在XML级别。
<MESSAGES>
<MESSAGE>
<RECIPIENT>Foo</RECIPIENT>
<PAYLOAD>
<!-- Large message containing many possible elements -->
</PAYLOAD>
<MESSAGE>
<MESSAGE>
<RECIPIENT>Bar</RECIPIENT>
<PAYLOAD>
<!-- Large message containing many possible elements -->
</PAYLOAD>
<MESSAGE>
</MESSAGES>
到目前为止,我注意到了两件事。如果我在父MESSAGES级别没有提供架构,我可以在PAYLOAD级别提供架构,这将正确验证PAYLOAD。但是,然后没有验证包装器。
<MESSAGES>
<MESSAGE>
<RECIPIENT>Foo</RECIPIENT>
<PAYLOAD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.payload.org"
xsi:schemaLocation="http://www.payload.org xsd/payload-type-a.xsd">
<!-- Large message containing many possible elements -->
</PAYLOAD>
<MESSAGE>
</MESSAGES>
我也可以反过来,即验证MESSAGES包装器,但忽略PAYLOAD,在整个XML上使用以下XSD:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.message.org">
<xs:element name="MESSAGES">
<xs:complexType>
<xs:sequence>
<xs:element name="MESSAGE" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="RECIPIENT" type="xs:string"/>
<xs:any processContents="skip"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
使用XML:
<MESSAGES xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.messages.org"
xsi:schemaLocation="http://www.messages.org xsd/messages.xsd">
<MESSAGE>
<RECIPIENT>Foo</RECIPIENT>
<PAYLOAD>
<!-- Large message containing many possible elements -->
</PAYLOAD>
<MESSAGE>
</MESSAGES>
但我不能做的是在XML中结合两个 XSD:
<MESSAGES xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.messages.org"
xsi:schemaLocation="http://www.messages.org xsd/messages.xsd">
<MESSAGE>
<RECIPIENT>Foo</RECIPIENT>
<PAYLOAD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.payload.org"
xsi:schemaLocation="http://www.payload.org xsd/payload-type-a.xsd">
<!-- Large message containing many possible elements -->
</PAYLOAD>
<MESSAGE>
</MESSAGES>
我对XSD很新,所以我可以看到我正在尝试做的可能不是XML /验证的精神,但它确实让我觉得这是一个合理的想法 - 我如果我是第一个提出反对意见的人,我会感到惊讶!
我能想到的唯一理论解决方案是让XSD本身由生成MESSAGES的XSLT动态生成。也就是说,使用XSLT(为简洁起见省略),输出XML和Schema来验证它。然后我可以使用XSD import语句,因为XSLT文档与PAYLOAD类型之间存在一对一的映射。
然而,这会使事情变得非常复杂!
我希望有一种方法可以使用不同的Schema验证XML文件的不同部分,并从XML文件本身控制它。
任何想法都非常有用!
答案 0 :(得分:1)
我最终得到了这个。现实情况是,我认为我做了一些小错误的事情,这意味着我无所事事。最终我能够生成以下内容 - 唯一缺少的是elementFormDefault="qualified"
属性中的xs:schema
,如果模式正确验证,则processContents
应为strict
。
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.message.org"
elementFormDefault="qualified">
<xs:element name="MESSAGES">
<xs:complexType>
<xs:sequence>
<xs:element name="MESSAGE" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="RECIPIENT" type="xs:string"/>
<xs:any processContents="strict"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
有了这个XSD,我能够使用以下XML:
<MESSAGES xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.messages.org"
xsi:schemaLocation="http://www.messages.org xsd/messages.xsd">
<MESSAGE>
<RECIPIENT>Foo</RECIPIENT>
<PAYLOAD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.payload.org"
xsi:schemaLocation="http://www.payload.org xsd/payload-type-a.xsd">
<!-- Large message containing many possible elements -->
</PAYLOAD>
<MESSAGE>
</MESSAGES>
最后值得注意的是,您可以在XML的顶部添加多个模式,然后通过更改xmlns
来选择它们,就像上面的示例一样:
<MESSAGES xsi:schemaLocation="http://www.messages.org xsd/messages.xsd
http://www.payload.org xsd/payload.xsd>"