Использование сущностных «констант» в XML-схеме - PullRequest
4 голосов
/ 27 июня 2011

Я пытаюсь создать схему 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.»

Ответы [ 3 ]

2 голосов
/ 29 июня 2011

Схема W3C XSD - это документ XML, поэтому объекты разрешены и поддерживаются. Когда файл схемы будет прочитан и обработан, сущности будут расширены для создания информационного набора XML.

http://www.xml.com/pub/a/2002/02/27/q-and-a.html

Кстати, XSD сам по себе является XML документ, конечно, так что есть ничто не мешает вам использовать сущности в самой схеме. (Это немного извращенно, требуя Схема использования DTD для объявления эти лица.) Вы просто не можете использовать XML-схема для объявления объектов для использования в других документах.

Объекты могут быть удобным способом избежать копирования / вставки и облегчить обслуживание файлов экземпляров XML.

Если он «взрывается» в собственном приложении Win32 при анализе схемы, это звучит как ошибка в MSXML 4.0 или собственном приложении Win32.

2 голосов
/ 08 июля 2011

Да, вы можете использовать сущности для определения констант в файле схемы XML.

Код подтверждается после попытки загрузки схемы.Причина: «Имя самого верхнего элемента должно совпадать с именем объявления DOCTYPE.»

<?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 не распознают пространство имен.Из-за этого анализатор видит DTD, который определяет корневой элемент <schema>, тогда как ваш документ имеет корневой элемент <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 ... >
0 голосов
/ 29 июня 2011

Вы можете сделать общий xsd и импортировать его из других схем.См. Импорт типов .

В схеме отчета report.xsd используется простой тип xipo: SKU, определенный в другой схеме и в другом целевом пространстве имен.

<import namespace="http://www.example.com/IPO"/>
...