xml - 在 XML 架构中使用实体 'constants'

标签 xml delphi xsd dtd msxml

我正在尝试创建一个 XML 架构,其中许多类型共享一些“魔数(Magic Number)”。

如果/当这些魔数(Magic Number)发生变化时,我不想在多个位置更改我的模式,而是想将它们拉出到某种常量定义中。

我尝试过将 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 架构文件中定义常量。

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 [反而。这个前缀“硬编码”可能看起来是错误的,但在 DTD 中没有简单的通用方法来进行命名空间前缀映射。

如果您在多个模式中使用相同的“魔数(Magic Number)”,那么您还可以在单​​独的 DTD 中定义实体,然后通过嵌入式 DTD 中的参数实体引用它来包含它。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xs:schema [
  <!ENTITY % magicNumbers SYSTEM "url/to/your/entity/dtd-document">
  %magicNumbers;
]>
<xs:schema ... >

关于xml - 在 XML 架构中使用实体 'constants',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6494189/

相关文章:

delphi - 如何在 Delphi XE3、Firemonkey2 中更新 TStringGrid 单元格

c# - 引用的 XmlSchemaElement 中的 IsAbstract 值不正确

xsd - xsd 模式中 'sequence' 的等价物是什么(但没有排序)

c++ - 将c++代码转换为xml文件进行代码分析

java - 如何向 XML 元素添加属性

xml - 使用 Xpath 选择特定元素的第一个子元素

c# - Delphi 编写的 DLL 发生内存访问冲突。尝试通过 DLLImport 访问

android - 如何删除 ListView 搜索框中的清除按钮?

xml - VB.NET 根据 XSD 文件验证 XML 文件并通过 xml 进行解析

python - lxml etree 在之前找到最接近的元素