动态 XML 架构验证文档的子部分 [英] Dynamic XML Schema Validates Subsection of Document

查看:26
本文介绍了动态 XML 架构验证文档的子部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的情况类似于带有来自其他命名空间的元素的 XSD",我有 2 个 XML 片段.

I have a situation similar to "XSD with elements from other namespace", where I have 2 peices of XML.

一个 XML 充当另一个 XML 的包装器.在一个简单的例子中 - 我们有一个 MESSAGES 包装器,包含至少一个 MESSAGE 元素.每个 MESSAGE 元素都包含一个根据 XSD 验证的 PAYLOAD.

One peice of XML acts as a wrapper to the other. In a simple example - we have a single MESSAGES wrapper, containing at least one MESSAGE elements. Each MESSAGE element contains a PAYLOAD which is validated against an XSD.

给定 MESSAGES 父级中的每个 PAYLOAD 将针对相同的 XSD 进行验证.但是,不同的 MESSAGES 可以包含针对整个 XSD 主机进行验证的 PAYLOAD.我确实有数百个 XSD 来验证不同类型的 PAYLOAD.

Each PAYLOAD in a given MESSAGES parent will validate against the same XSD. However, different MESSAGES can contain PAYLOADs that validate against a whole host of XSDs. I literally have hundreds of XSDs to validate different types of PAYLOAD.

我想拥有自己的 XSD 来验证 MESSAGES 包装器的结构,然后将验证 PAYLOAD 的责任移交给我拥有的众多库存 XSD 之一,具体取决于 PAYLOAD 类型.

I want to have my own XSD that validates the structure of the MESSAGES wrapper, and then handsover responsibility of validating the PAYLOAD to one of the many stock XSDs I have, depending on PAYLOAD type.

重要的一点是我们不能将 PAYLOAD XSD 导入 MESSAGE XSD - 因为 PAYLOAD 模式类型在 XSD 级别不是固定的.但它在 XML 级别是固定的.

The important point is we cannot import the PAYLOAD XSD into the MESSAGE XSD - because the PAYLOAD schema type is not fixed at XSD-level. But it is fixed at XML-level.

<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.但是,没有对包装器进行验证.

Two things I've noticed so far. If I provide no schema at the parent MESSAGES level, I can provide a schema at PAYLOAD level, and this will correctly validate the PAYLOAD. However there is no validation of the wrapper then.

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

I can also do the reverse, i.e. validate the MESSAGES wrapper, but ignore the PAYLOAD, using the following XSD on the whole of XML:

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

But what I can't do is combine both XSDs inside the 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>

我是 XSD 的新手,所以我可以看出我正在尝试做的事情可能不符合 XML/验证的精神,但它确实让我觉得这是一件合理的事情 - 我'如果我是第一个提出反对意见的人,我会感到惊讶!

I'm newish to XSD, so I can kinda see that what I'm trying to do is perhaps not in the spirit of XML/Validation, but it does strike me as a reasonable thing to want to do - I'd be suprised if I'm the first person who has come-up against this!

我能想到的唯一理论解决方案是让 XSD 本身由生成 MESSAGES 的 XSLT 动态生成.也就是说,使用 XSLT(为简洁起见省略),输出 XML 和 Schema 以对其进行验证.然后我可以使用 XSD 导入语句,因为有一个 XSLT 文档到 PAYLOAD 类型的一对一映射.

The only theoretical solution that I can dream-up is to have the XSDs themselves dynamically generated by the XSLT that generates the MESSAGES. That is, have the XSLT (omitted for brevity), output both the XML and the Schema to validate it. Then I could use the XSD import statement, as there is a 1-to-1 mapping of XSLT document to PAYLOAD type.

然而,这会使事情变得非常复杂!

This will significantly complicate things however!

我希望有一种方法可以验证具有不同架构的 XML 文件的不同部分,并从 XML 文件本身进行控制.

I'm hoping there is a way of validating different parts of an XML file with different Schemas, and controlling that from the XML file itself.

非常感谢任何想法!

推荐答案

我最终完成了这项工作.现实情况是,我认为我做错了一些小事,这意味着我一直在兜圈子.最终我能够生成以下内容 - 唯一缺少的是 xs:schema 属性中的 elementFormDefault="qualified"processContents> 如果模式验证正确,则应该是 strict.

I got this working in the end. The reality is that I think I was doing a few little things wrong, that meant I went around in circless. Eventually I was able to produce the following - the only thing missing was elementFormDefault="qualified" in the xs:schema atributes, and that the processContents should be strict if the schemas are validating correctly.

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

Armed with this XSD I was able to get the following XML to work:

<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 来选择它们:

Finally it's worth noting that you can add multiple schemas at the top of the XML and then select them by altering the xmlns just like the above example:

<MESSAGES xsi:schemaLocation="http://www.messages.org xsd/messages.xsd
                              http://www.payload.org xsd/payload.xsd>"

这篇关于动态 XML 架构验证文档的子部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆