我的目标是对我的XSD元素定义进行简单限制:我想定义一个元素,以便
<xs:annotation><xs:documentation>
都需要</xs:documentation></xs:annotation>
<xs:element>
,“note_author”和“note_added”属性已添加到<xs:documentation>
元素。通过以下内容,我可以让Schema 2进行验证,但我无法执行上面提到的规则,我想在Schema 1中声明。
我希望使用经过修改的,经过验证的XSD架构(架构2)实现的目标:
SCHEMA2。
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ds="http://documentation_schema">
<xs:import namespace="http://documentation_schema"
schemaLocation="documentation_schema.xsd"/>
<xs:element name="document"
ds:created="2013-06-20"
ds:last_modified="2013-06-20">
<xs:annotation>
<xs:documentation ds:note_author="xsd_user1"
ds:note_added="2013-06-20">
The root element for a document
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element ref="subelement"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="subelement" type="xs:string"
ds:created="2013-06-20"
ds:last_modified="2013-07-20">
<xs:annotation>
<xs:documentation ds:note_author="xsd_user1"
ds:note_added="2013-06-20">
A subelement child of document
</xs:documentation>
<xs:documentation ds:note_author="xsd_user2"
ds:note_added="2013-07-20">
changed from complex to string type
</xs:documentation>
</xs:annotation>`
</xs:element>
</xs:schema>
架构1(documentation_schema) - 我想要验证架构2的架构:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://documentation_schema">
<xs:attribute name="created" type="xs:date"/>
<xs:attribute name="last_modified" type="xs:date"/>
<xs:attribute name="note_added" type="xs:date"/>
<xs:attribute name="note_author">
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="xsd_user1"/>
<xs:enumeration value="xsd_user2"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:schema>
答案 0 :(得分:4)
好问题!
应该提出几点:
首先,正如我猜你已经知道的那样(虽然问题的一些读者和这个答案可能没有),但你的架构文件1已经合法。因此,您不需要 来修改架构文档的架构,以使其合法化。但是,如果我理解正确的话,你希望它不仅仅是有效的;你想要它的变体,其中元素声明在没有xs:documentation元素的情况下发生,或者没有ds:added和ds:last_modified属性,无效。
其次,可以按照您描述的方式修改XSD架构文档的XSD架构,并且原则上可以根据架构文档的修改架构验证架构文档。
但是,允许模式验证器具有任意名称空间中某些模式组件的内置知识,并且它们 required 具有XSD名称空间的内置知识。因此,符合模式验证器可以查看验证模式文档1的请求,比如说#A;我已经知道我需要了解的关于命名空间http://www.w3.org/2001/XMLSchema的所有内容,我不需要阅读用户提供的架构文档&#34;,然后不强制执行您指定的其他约束。
具体地说,在我的测试中,我能够使用Xerces J来针对模式文档的修改模式验证模式文档,但是Saxon似乎忽略了修改并且规则模式文档有效,即使元素声明缺少必需的属性。
同样,在根据您编写的模式验证文档时,不可能要求您的XSD验证程序反对不符合您的高要求的模式文档。
有了这些背景点,这就是你需要做的事情。
您不需要将ds架构导入到架构文档中1.导入它意味着您可以将对ds:added等属性的引用添加到您的类型中在模式文档1中声明 - 也就是说,它将其导入到为目标名称空间定义的模式中。它对用于验证模式文档的模式没有影响(模式是命名空间http://www.w3.org/2001/XMLSchema的模式)。
您需要创建一个模式来修改模式文档的标准模式,而不仅仅是通过添加新组件,而是通过重新定义或覆盖模式文档的现有模式中的组件。有两种方法可以做到这一点:使用xs:redefine,和(在XSD 1.1中)使用xs:override。在XSD 1.1中,不推荐使用xs:redefine,因为它的规范已被证明是不完整和/或不一致的,并且对于某些使用它的方式,跨处理器的互操作性很差。
您需要使用XSD验证程序根据架构文档的修改架构验证架构文档。如上所述,这可能不适用于所有验证器。如果您在处理XSD验证器时遇到问题,您可能需要考虑编写Schematron架构来强制执行您提到的一些约束,并将Schematron验证构建到您的工作流程中。 (Schematron的一个优点是,只验证文档中的一些独立方面非常容易。在某些情况下这可能是一个缺点,但在这个或其他需要增加一点验证的情况下则不是。如果您的用户名表明您是XSLT用户,Schematron可能会对您感到很自然。)
作为测试,我使用xs:override来修改XSD 1.1的架构文档的架构;架构文档如下所示,我希望这些评论能够清楚地说明发生了什么。如果您只能访问XSD 1.0处理器,则需要使用xs:redefine;一些细节将会改变。
<?xml version='1.0'?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ds="http://documentation_schema"
blockDefault="#all"
elementFormDefault="qualified"
xml:lang="en"
targetNamespace="http://www.w3.org/2001/XMLSchema"
version="Id: structures.xsd,v 1.2 2004/01/15 11:34:25 ht Exp ">
<xs:annotation>
<xs:documentation>
This schema document redefines some things in the schema for
schema documents.
First we import the ds and xml namespaces.
</xs:documentation>
</xs:annotation>
<xs:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xs:import namespace="http://documentation_schema"
schemaLocation="xslt_user_schema2.xsd">
<xs:annotation>
<xs:documentation>
Get access to the ds:* attributes.
</xs:documentation>
</xs:annotation>
</xs:import>
<xs:annotation>
<xs:documentation>
Then we include the schema for schema documents defines in XSD 1.1, with
some modifications.
</xs:documentation>
</xs:annotation>
<xs:override schemaLocation="sfsd-11.xsd">
<xs:annotation>
<xs:documentation>
The schema document "sfsd-11.xsd" is our local copy of the
XSD 1.1 schema for schema documents.
</xs:documentation>
</xs:annotation>
<xs:element name="documentation" id="documentation"
type="xs:documentation-extended">
<xs:annotation>
<xs:documentation>
Here, we change the xs:documentation element from using
a local complex type to using a named type (declared below).
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="annotation" id="annotation">
<xs:annotation>
<xs:documentation>
Next, we require xs:annotation elements to contain
at least one xs:documentation element.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:complexContent>
<xs:extension base="xs:openAttrs">
<!--* modified the content model to require at least one
* occurrence of xs:documentation
*-->
<xs:sequence>
<xs:element ref="xs:appinfo" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="xs:documentation"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="xs:appinfo"/>
<xs:element ref="xs:documentation"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="id" type="xs:ID"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<!--* Finally, we override the complex type used for all forms
* of element declarations, by including the attribute group
* xs:schema-documentation-attributes (defined below).
* Note that we cannot include references to the attributes
* directly, because the default schema for schema documents
* doesn't import the ds namespace. One level of indirection,
* however, suffices to solve the problem.
*-->
<xs:complexType name="element" abstract="true">
<xs:annotation>
<xs:documentation>
The element element can be used either
at the top level to define an element-type binding globally,
or within a content model to either reference a globally-defined
element or type or declare an element-type binding locally.
The ref form is not allowed at the top level.</xs:documentation>
<xs:documentation>
This modification of the type adds two required attributes:
ds:added and ds:last_modified. They will be inherited by
all the various restrictions of this type.
</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="xs:annotated">
<xs:sequence>
<xs:choice minOccurs="0">
<xs:element name="simpleType" type="xs:localSimpleType"/>
<xs:element name="complexType" type="xs:localComplexType"/>
</xs:choice>
<xs:element name="alternative" type="xs:altType"
minOccurs="0" maxOccurs="unbounded"/>
<xs:group ref="xs:identityConstraint" minOccurs="0"
maxOccurs="unbounded"/>
</xs:sequence>
<xs:attributeGroup ref="xs:defRef"/>
<xs:attribute name="type" type="xs:QName"/>
<xs:attribute name="substitutionGroup">
<xs:simpleType>
<xs:list itemType="xs:QName"/>
</xs:simpleType>
</xs:attribute>
<xs:attributeGroup ref="xs:occurs"/>
<xs:attribute name="default" type="xs:string"/>
<xs:attribute name="fixed" type="xs:string"/>
<xs:attribute name="nillable" type="xs:boolean" use="optional"/>
<xs:attribute name="abstract" type="xs:boolean" default="false"
use="optional"/>
<xs:attribute name="final" type="xs:derivationSet"/>
<xs:attribute name="block" type="xs:blockSet"/>
<xs:attribute name="form" type="xs:formChoice"/>
<xs:attribute name="targetNamespace" type="xs:anyURI"/>
<!--* add the ds:* attributes *-->
<xs:attributeGroup ref="xs:schema-documentation-attributes"/>
<!--* end of added material. *-->
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:override>
<xs:complexType name="documentation-extended" mixed="true">
<xs:annotation>
<xs:documentation>
This complex type is just like the usual type for the
xs:documentation element, except that it reuqires the
ds:note_author and ds:note_added attributes.
</xs:documentation>
</xs:annotation>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:any processContents="lax"/>
</xs:sequence>
<xs:attribute name="source" type="xs:anyURI"/>
<xs:attribute ref="xml:lang"/>
<!--* additions ... *-->
<xs:attribute ref="ds:note_author" use="required"/>
<xs:attribute ref="ds:note_added" use="required"/>
<!--* end added material *-->
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
<xs:attributeGroup name="schema-documentation-attributes">
<xs:annotation>
<xs:documentation>
This attribute group serves to include the two
attributes specified in the complex type for
element declarations.
</xs:documentation>
</xs:annotation>
<xs:attribute ref="ds:created" use="required"/>
<xs:attribute ref="ds:last_modified" use="required"/>
</xs:attributeGroup>
</xs:schema>
添加以回应评论。
1(a)中。我仍然需要有一个用于验证模式文档的模式的本地副本,对吧? (在你的情况下:sfsd-11.xsd,在我的例子中:在w3.org/2001/XMLSchema上找到的模式?[但是我选择命名吗?)?
要使用覆盖(在XSD 1.1中)或重新定义(在1.0或1.1中),您需要指向要修改的模式的schemaLocation。如果您有架构文档架构的本地副本,您当然可以指向它,但同样可以指向W3C服务器上的副本。所以:不,你不需要&#34;需要&#34;有本地副本。但是你很可能想要:W3C的服务器每次解析XML文档时都会尝试取消引用DTD和模式文档,而W3C的系统管理员通过让服务器响应来做出响应这种要求非常缓慢。如果这样的本地副本可能更方便,即使它在任何意义上都不需要。
1(b)中。当我尝试保存在w3.org/2001/XMLSchema中找到的模式的本地副本时,我得到该模式的验证错误,并引用了&#39; xs:发生&#39;已经宣布了。&#39;如果我注释掉那个属性组,我会得到类似的错误。
当您尝试保存时?听起来好像您的文件系统正在对您保存的文件执行模式验证;这将是新颖的行为。我怀疑你看到的验证错误是在其他一些情况下出现的;在不知道验证器试图做什么以及如何调用它的情况下,很难说出这里发生了什么。有关属性组xs:的消息已经被声明,表明您的验证器正在查看模式文档的模式两次;要么是因为它了解了内置的命名空间(在这种情况下,您可能无法使验证器完全使用修改后的模式),或者因为您放置模式的方式有误一起,或者因为调用验证器的方式有误。
1(c)。请注意,我已将XMLSchema.dtd标头包含在我的本地保存模式的顶部(并在本地保存了dtd)我的本地模式的属性:
<!DOCTYPE schema SYSTEM "XMLSchema.dtd">
<xs:schema targetNamespace="w3.org/2001/XMLSchema"
blockDefault="#all"
elementFormDefault="qualified"
version="1.0"
xmlns:xs="w3.org/2001/XMLSchema"
xml:lang="EN"
xmlns:hfp="w3.org/2001/XMLSchema-hasFacetAndProperty"
finalDefault=""
attributeFormDefault="unqualified">
这里没有明显的问题。严格来说,文件类型声明并不是必需的,但如果您没有遇到“无法找到DTD”的话。错误,它可能没有任何伤害。
1(c)(续)当我删除xmlns时:xs =&#34; w3.org/2001/XMLSchema" ;; (我怀疑它会摆脱重复的定义错误,我得到另一个错误,指出&#34;元素&#39; xs:schema&#39;没有声明名为&#39; xmlns:hfp&#39的属性;&#34;你或任何人可以告诉我这里我做错了什么吗?
您有一个文档,几乎在每个元素上使用名称空间前缀xs
。您不想要删除该前缀的名称空间绑定。
使XSD验证器使用模式文档的模式的修改形式,这是使用XSD的高级主题。 (只要你使用语言L来描述并可能修改语言L,就很容易将自己变成对象语言和元语言之间的混淆。请问离你最近的大师他们需要多长时间才能理解第一个元语言。他们研究过的循环翻译。)
如果您正处于使用XML和XSD的阶段,您对在一个架构文档中删除命名空间声明的可能影响有任何疑问,您可能会发现您执行的任务非常具有挑战性。我不会说你不应该花时间,因为我不会告诉青少年不要花时间重建引擎。它可能很有趣,你可能会学到很多东西。但是,如果你不是以此为目的,那么你需要知道它不会快速或简单。通过这种方式摆弄命名空间声明,你不太可能让它工作。 (在此背景下,我建议您阅读the story of Tom Knight and the Lisp Machine。)