我正在尝试创建一个 XML模式,其中许多类型共享一些“魔术数字”. 如果/当这些魔术数字发生变化时,我不想在几个位置更改我的模式,而是想将它们拉出来进行某种不变的定义. 我已经玩
如果/当这些魔术数字发生变化时,我不想在几个位置更改我的模式,而是想将它们拉出来进行某种不变的定义.
我已经玩过将DTD添加到我的模式并在此处声明一些实体.但我绝不是DTD的专家,虽然它似乎在使用模式的C#应用程序中工作,但是还有一个本机Win32应用程序使用与msxml 4.0相同的模式,这会爆炸……
有没有人有这种方式扩展模式定义的经验(可以这样做),还是有更好的方法?
(编辑:一个例子)
示例XML:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE schema [ <!ENTITY SomeMagicNumber "10">]> <xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:mstns="http://tempuri.org/XMLSchema.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:simpleType name="MySimpleType"> <xs:restriction base="xs:int"> <xs:maxInclusive value="&SomeMagicNumber;" /> </xs:restriction> </xs:simpleType> <xs:complexType name="MyIntegers"> <xs:sequence> <xs:element name="value" type="xs:int" maxOccurs="&SomeMagicNumber;" /> </xs:sequence> </xs:complexType> <xs:complexType name="MyFloats"> <xs:sequence> <xs:element name="value" type="xs:float" maxOccurs="&SomeMagicNumber;" /> </xs:sequence> </xs:complexType> </xs:schema>
示例Delphi Win32代码加载架构:
var XmlSchemas: IXMLDOMSchemaCollection; XmlSchema: IXMLDOMDocument2; XmlDocument: IXMLDOMDocument2; begin XmlSchemas := CoXMLSchemaCache40.Create; XmlSchema := CoDOMDocument40.Create; XmlSchema.load((*INSERT SCHEMA PATH HERE*)); Assert(XmlSchema.parseError.errorCode = 0, XmlSchema.parseError.reason); XmlSchemas.add((*INSERT SCHEMA TARGET NAMESPACE HERE*), XmlSchema); XmlDocument := CoDOMDocument40.Create; XmlDocument.schemas := XmlSchemas; XmlDocument.validateOnParse := True; end;
尝试加载架构后代码断言.原因:’最顶层元素的名称必须与DOCTYPE声明的名称相匹配.
是的,您可以使用实体在XML Schema文件中定义常量.The code asserts after attempting to
load the schema. Reason: ‘The name of
the top most element must match the
name of the DOCTYPE declaration.’
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE schema [ <!ENTITY SomeMagicNumber "10"> ]> <xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:mstns="http://tempuri.org/XMLSchema.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema"> ...(clipped away) </xs:schema>
您的问题是由DTD不支持名称空间的事实引起的.因此,解析器会看到一个定义根元素< schema>的DTD.而您的文档有一个根元素< xs:schema>.尝试使用<!DOCTYPE xs:schema [而不是.这个前缀“hardcoding”可能看似错误,但在DTD中,没有简单的通用方法来获得名称空间前缀映射. 如果在多个模式中使用相同的“幻数”,那么您还可以在单独的DTD中定义实体,然后通过嵌入式DTD中的参数实体引用它来包含它.
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xs:schema [ <!ENTITY % magicNumbers SYSTEM "url/to/your/entity/dtd-document"> %magicNumbers; ]> <xs:schema ... >