如何使用自定义元素扩展基础架构,同时保持打开状态以更改新版本?

Vic*_*tor 9 xml xsd xsd-validation

鉴于XSD如下:

<xs:schema elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"  xmlns:std="http://..." targetNamespace="...">
  <xs:element name="SomeRootNode" type="std:SomeRootNodeType" />
  ...
</xs:schema>
Run Code Online (Sandbox Code Playgroud)

它定义了一些允许来自不同命名空间的子进程的元素.

我想用自己的模式扩展这个模式,并在基础文档中插入子元素和特定元素的属性.例如,myElementX或myAttributeY必须具有父节点std:SomeRootNode.然后,组合文档应该能够允许任何第三方继续以基本模式已经允许的任何方式扩展文档,但是对于来自我的命名空间的元素和属性,我想验证所有元素和属性是否具有正确的父节点并仅出现在基本文档中允许的位置.

怎么能实现这一目标?

我希望有一个干净的解决方案,而不是重新定义我扩展的基础架构.如果发布新版本的基础架构,我希望能够轻松适应.每次发布新版本的基础文档时,我都不想用新的重新定义来改变我的(除非它对我的设计有重大改变).

Spr*_*tty 13

在扩展现有的XML Schema时,有一些选择.

使用基础架构

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Root" type="RootType" />
    <xs:complexType name="RootType">
        <xs:sequence>
            <xs:element name="OriginalContent" />
        </xs:sequence>
    </xs:complexType>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)

图形模式表示

扩展/限制

您可以扩展/限制类型,这有效地创建了具有额外/更少元素/属性的新类型,但是无法强制使用此新类型.XML的创建者可以使用xsi:type ="MyCustomType"告诉您他们正在使用他们的新类型,但您不能坚持使用它.

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:include schemaLocation=".\Root.xsd" />
    <xs:complexType name="MyNewRoot">
        <xs:complexContent>
            <xs:extension base="RootType">
                <xs:sequence>
                    <xs:element name="AdditionalElement" type="xs:string" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)

图形模式表示

示例XML文件

<?xml version="1.0" encoding="utf-8"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="Extension.xsd" 
      xsi:type="MyNewRoot">
    <OriginalContent />
    <AdditionalElement/>
</Root>
Run Code Online (Sandbox Code Playgroud)

图形模式表示

重新定义

另一种选择是使用<redefine>.基本上取代了RootType的定义,因此无论RootType出现在哪里,我们现在都必须使用新版本.

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:redefine schemaLocation="root.xsd">
        <xs:complexType name="RootType">
            <xs:complexContent>
                <xs:extension base="RootType">
                    <xs:sequence>
                        <xs:element name="MyContent" type="xs:string" />
                    </xs:sequence>
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    </xs:redefine>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)

示例XML文件

<?xml version="1.0" encoding="utf-8"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Redefine.xsd">
    <OriginalContent></OriginalContent>
    <MyContent>stuff</MyContent>
</Root>
Run Code Online (Sandbox Code Playgroud)

任何

另一种解决方案是xs:any在基本元素定义中包括a .但是,如果您不控制基础架构,则无法执行此操作.

打开内容

**仅适用于XSD 1.1**

Open Content是专门添加的,允许您创建开放模式,它具有2'模式的交错和后缀.当设置为交错时,其他元素(匹配包含的xs:any子句)可以在元素之间交错(在任何现有元素之前,之间和之后).在后缀模式下,可以在现有元素之后添加其他元素(匹配包含的xs:any子句).

OpenContent可以应用于特定的complexTypes,也可以在模式级别应用,其中它适用于在其中声明的所有元素.

如果您使用的是XSD 1.1,这绝对是为了使您的模式可扩展的方法,但XSD 1.1仍然不受支持.

<xs:complexType name="BookType">
    <xs:openContent mode="interleave">
        <xs:any />
    </xs:openContent>
    <xs:sequence>
        <xs:element name="Title"  type="xs:string" />
        <xs:element name="Author" type="xs:string" maxOccurs="unbounded" />
        <xs:element name="ISBN"   type="xs:string" />
    </xs:sequence>
</xs:complexType>
Run Code Online (Sandbox Code Playgroud)

图形模式表示

还应该注意的是,如果您在现有元素的运行之间交错元素(即标题,作者,新元素,作者,ISBN),那么大多数解析器会将第二个作者视为"新"元素并使用openContent规则验证它在XS:元素的名称="作者"类型="XS:字符串",而且若作者有2的的minOccurs,这一条款可能会失败,因为它看到1xAuthor,1xNewElement,1xAuthor和第一1xAuthor不完全的的minOccurs条款.

摘要

所有这些方法都有起伏,但拥有一个好的XML编辑器,可以更容易地弄清楚发生了什么.

我推荐由我公司制作的Liquid XML Studio ,因为它有一个很好的XSD编辑器,可以从您的模式创建示例XML,使您可以轻松查看工作结果,XML Intellisense也可以轻松查看有效的XML选项.