微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在XML Schema中使用实体’常量’

我正在尝试创建一个 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 ... >

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。