使用自定义属性扩展现有 XSD 架构
Extend existing XSD schema with custom attribute
我需要向 xml 文件添加一些自定义属性,该文件由现有的、已定义的模式验证。
给定现有 xml 个元素:
<existingElement attr1="1" attr2="2" />
已使用现有 xsd 架构进行验证,我希望能够向此元素添加自定义属性,而不会在此过程中破坏架构验证:
<existingElement attr1="1" attr2="2" xmlns:my="http://example.com/node" my:id="myNodeId" />
无法修改原始schema文件,它确实有任何属性元素
我应该采取什么方法?
我尝试添加另一个 xsd 文件:
<xs:schema
targetNamespace="http://example.com/node"
attributeFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:attribute name="id" type="xs:string" />
</xs:schema>
但我一直收到 Attribute 'http://example.com/node:id' was not declared
。
我在 .NET
中使用 XmlSchemaSet
进行验证,同时添加了新旧模式。
在某种程度上,您必须修改现有架构,因为您正试图创建一个违反其约束之一的实例文档。
如果原始模式使用命名的复杂类型定义结构,则您可以使用以下两种机制之一修改现有模式,而无需对模式文档的文本进行文本更改:xs:redefines
,或定义一个使用 "derivation by extension" 的新复杂类型。这两者都在不修改架构文档的情况下修改了架构:所以这有点取决于您不修改架构的要求的意思。请注意,如果您使用 "derivation by extension",那么您的实例将必须通过包含命名扩展复杂类型的 xsi:type
属性来标记它使用扩展。
如果您担心修改模式是关于分叉 XSD 源定义,那么定义修改后的模式的另一种方法是将 XSLT 转换应用于原始模式。这实际上与 xs:redefines 非常相似,只是您可以进行任何您喜欢的更改,而 xs:redefined 限制了您可以更改的内容。
另一方面,如果您关心的是确保符合新模式的文档仍然与使用旧模式的应用程序兼容,那么所有这些机制都会失败:在所有情况下,您正在创建的文档不不符合现有模式,因此有可能破坏依赖文档对该模式有效的应用程序。
test.xml
<?xml version="1.0" encoding="utf-8"?>
<existingElement attr1="1" attr2="2" xmlns:my="http://example.com/node" my:id="myNodeId" />
test1.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="existingElement">
<xs:complexType>
<xs:attribute name="attr1" type="xs:unsignedByte" use="required" />
<xs:attribute name="attr2" type="xs:unsignedByte" use="required" />
<xs:anyAttribute />
</xs:complexType>
</xs:element>
</xs:schema>
test2.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://example.com/node"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:attribute name="id" type="xs:string" />
</xs:schema>
C#代码
var schemaSet = new XmlSchemaSet();
schemaSet.Add("", "test1.xsd");
schemaSet.Add("http://example.com/node", "test2.xsd");
schemaSet.Compile();
var xml = XDocument.Load("test.xml");
xml.Validate(schemaSet, (o, e) =>
{
Console.WriteLine(e.Severity + ": " + e.Message);
});
有效。没有验证错误。
我需要向 xml 文件添加一些自定义属性,该文件由现有的、已定义的模式验证。
给定现有 xml 个元素:
<existingElement attr1="1" attr2="2" />
已使用现有 xsd 架构进行验证,我希望能够向此元素添加自定义属性,而不会在此过程中破坏架构验证:
<existingElement attr1="1" attr2="2" xmlns:my="http://example.com/node" my:id="myNodeId" />
无法修改原始schema文件,它确实有任何属性元素
我应该采取什么方法?
我尝试添加另一个 xsd 文件:
<xs:schema
targetNamespace="http://example.com/node"
attributeFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:attribute name="id" type="xs:string" />
</xs:schema>
但我一直收到 Attribute 'http://example.com/node:id' was not declared
。
我在 .NET
中使用 XmlSchemaSet
进行验证,同时添加了新旧模式。
在某种程度上,您必须修改现有架构,因为您正试图创建一个违反其约束之一的实例文档。
如果原始模式使用命名的复杂类型定义结构,则您可以使用以下两种机制之一修改现有模式,而无需对模式文档的文本进行文本更改:xs:redefines
,或定义一个使用 "derivation by extension" 的新复杂类型。这两者都在不修改架构文档的情况下修改了架构:所以这有点取决于您不修改架构的要求的意思。请注意,如果您使用 "derivation by extension",那么您的实例将必须通过包含命名扩展复杂类型的 xsi:type
属性来标记它使用扩展。
如果您担心修改模式是关于分叉 XSD 源定义,那么定义修改后的模式的另一种方法是将 XSLT 转换应用于原始模式。这实际上与 xs:redefines 非常相似,只是您可以进行任何您喜欢的更改,而 xs:redefined 限制了您可以更改的内容。
另一方面,如果您关心的是确保符合新模式的文档仍然与使用旧模式的应用程序兼容,那么所有这些机制都会失败:在所有情况下,您正在创建的文档不不符合现有模式,因此有可能破坏依赖文档对该模式有效的应用程序。
test.xml
<?xml version="1.0" encoding="utf-8"?>
<existingElement attr1="1" attr2="2" xmlns:my="http://example.com/node" my:id="myNodeId" />
test1.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="existingElement">
<xs:complexType>
<xs:attribute name="attr1" type="xs:unsignedByte" use="required" />
<xs:attribute name="attr2" type="xs:unsignedByte" use="required" />
<xs:anyAttribute />
</xs:complexType>
</xs:element>
</xs:schema>
test2.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://example.com/node"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:attribute name="id" type="xs:string" />
</xs:schema>
C#代码
var schemaSet = new XmlSchemaSet();
schemaSet.Add("", "test1.xsd");
schemaSet.Add("http://example.com/node", "test2.xsd");
schemaSet.Compile();
var xml = XDocument.Load("test.xml");
xml.Validate(schemaSet, (o, e) =>
{
Console.WriteLine(e.Severity + ": " + e.Message);
});
有效。没有验证错误。