我想创建一个XSD,它定义一个属性,该属性可以放在来自其他模式的元素或不在任何模式中的元素上。例如,架构看起来像这样:
<xs:schema id="MySchema"
targetNamespace="http://tempuri.org/MySchema"
elementFormDefault="qualified"
xmlns="http://tempuri.org/MySchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:attribute name="myAttribute" />
</xs:schema>
文档看起来像这样:
<someElement xmlns="http://tempuri.org/OtherSchema" xmlns:m="http://tempuri.org/MySchema">
<someOtherElement someAttribute="value" m:myAttribute="value2" />
</someElement>
此示例中的“OtherSchema”如下所示:
<xs:schema id="OtherSchema"
targetNamespace="http://tempuri.org/OtherSchema"
elementFormDefault="qualified"
xmlns="http://tempuri.org/OtherSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:element name="someElement">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="someOtherElement">
<xs:complexType>
<xs:attribute name="someAttribute" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
可以从http://dl.getdropbox.com/u/407740/SchemaTest.zip下载完整的示例,包括执行验证的C#控制台应用程序。我的目标是在不必修改“OtherSchema”的情况下进行验证。这可能吗?
答案 0 :(得分:1)
我必须添加一个包装器,将两个不同的模式导入一个(因为xmllint只接受一个xml模式):
<xs:schema id="Wrapper" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation="MySchema.xsd" namespace="http://tempuri.org/MySchema"/>
<xs:import schemaLocation="OtherSchema.xsd" namespace="http://tempuri.org/OtherSchema"/>
</xs:schema>
我可以获得类似问题的唯一方法是编辑OtherSchema,xsd(问题不允许),所以附加一个属性通配符(在现有的之后):
<xs:attribute name="someAttribute" />
<xs:anyAttribute namespace="##other"/>
我不足以让XML Schema的专家说“这是不可能的”,但对我来说似乎是不可能的。
您的提案存在的一个问题是您未指定应在何处显示新属性。通常,如果声明属性(或复杂元素,模型组等),您可以自由引用它。如果您没有明确引用它,它就没有效果。因此,我认为您的提案将被视为已声明但未提及的属性。
你真正想要的是一种说“将此属性添加到每个现有complexType”的方法 - 但你不这么说。并且,不幸的是,似乎没有办法说出这一点。 (甚至没有办法说“将此属性添加到此特定的现有complexType” - 您必须将其包含在原始定义中或根本不包含。)
部分执行此操作的一种方法是在另一个模式中使用<redefine>
类型 - 我将在第二个答案中添加此类型。
答案 1 :(得分:1)
您可以重新定义架构,随意扩展它们。通过这种方式,您可以修改现有模式的定义,而无需实际更改文件。但是它不适用于给定的示例,因为无法重新定义元素(只有复杂类型等等 http://www.w3.org/TR/xmlschema-1/#element-redefine)。因此,我已将您的示例分解为显式complexTypes,因此它们会被公开以进行重新定义。
<强> RedefineOtherSchema.xsd:强>
<xs:schema id="RedefineOtherSchema"
targetNamespace="http://tempuri.org/OtherSchema"
elementFormDefault="qualified"
xmlns="http://tempuri.org/OtherSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:m="http://tempuri.org/MySchema"> <!-- for the ref -->
<xs:import schemaLocation="MySchema.xsd"
namespace="http://tempuri.org/MySchema"/> <!-- import -->
<xs:redefine schemaLocation="OtherSchema.xsd"> <!-- redefine -->
<xs:complexType name="SomeOtherElement">
<xs:complexContent>
<xs:extension base="SomeOtherElement">
<xs:attribute ref="m:myAttribute" /> <!-- the ref -->
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
</xs:schema>
<强> OtherSchema:强>
<xs:schema id="OtherSchema"
targetNamespace="http://tempuri.org/OtherSchema"
elementFormDefault="qualified"
xmlns="http://tempuri.org/OtherSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:element name="someElement" type="SomeElement"/>
<xs:complexType name="SomeElement">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded"
name="someOtherElement" type="SomeOtherElement"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SomeOtherElement">
<xs:attribute name="someAttribute" />
</xs:complexType>
</xs:schema>
MySchema:(未更改)
<xs:schema id="MySchema"
targetNamespace="http://tempuri.org/MySchema"
elementFormDefault="qualified"
xmlns="http://tempuri.org/MySchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:attribute name="myAttribute"/>
</xs:schema>
为什么<complexContent>
?
重新定义必须是现有类型的扩展(或限制) - 它是如何修改先前的定义。扩展必须在<complexContent>
(我相信)。
为什么<import>
?
您无法在xsd中的多个命名空间中定义事物(只有一个“targetNamespace”)。但是你可以通过从另一个xsd导入定义来解决这个问题(然后你没有“定义”它)。 [还有另一种方式吗?]
HTH: - )
答案 2 :(得分:0)
这正是NVDL(基于命名空间的验证和调度语言)所提供的。它允许组合多个模式/词汇表来验证文档,而无需更改这些模式。 NVDL是ISO标准。
处理您案例的工作NVDL脚本位于
之下<rules xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0" startMode="other">
<mode name="other">
<namespace ns="http://tempuri.org/OtherSchema">
<validate schema="other.xsd" useMode="validateMyAttributes"/>
</namespace>
</mode>
<mode name="validateMyAttributes">
<namespace ns="http://tempuri.org/MySchema" match="attributes">
<validate schema="my.xsd"/>
</namespace>
</mode>
</rules>
基本上它说使用other.xsd架构验证了... tempuri.org/OtherSchema命名空间的内容以及来自... tempuri.org/MySchema和my.xsd架构的属性。
有关NVDL的更多信息,请访问www.nvdl.org。上面的脚本是用oNVDL测试的。
答案 3 :(得分:-1)
考虑xsi:nil,xsi:schemaLocation和xsi:noNamespaceSchemaLocation。答案是肯定的。
也不会花很长时间尝试并看到它。
您在架构中缺少targetNamespace。试试这个:
<xs:schema xmlns="MySchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="MySchema">
<xs:attribute name="myAttribute" />
</xs:schema>