#xsd
#xsd
Вопрос:
Начиная с годичной разработки XSD / XML, я хочу написать более простой XSD, предназначенный только для элементов, которые не будут изменены или удалены, который может проверять XML из полного XSD.
Чтобы упростить:
С помощью этого XML:
<root>
<unknown1/>
<known2/>
<unknown2/>
<known1/>
<unknown3/>
<unknown4/>
</root>
И этот XSD:
<xsd:schema>
<xsd:element name="root">
<xsd:all>
<xsd:element name="unknown1" minOccurs="0"/>
<xsd:element name="unknown2" minOccurs="0"/>
<xsd:element name="unknown3" minOccurs="0"/>
<xsd:element name="unknown4" minOccurs="0"/>
<xsd:element name="known1" minOccurs="0"/>
<xsd:element name="known2" minOccurs="0"/>
</xsd:all>
</xsd:element name="root">
</xsd:schema>
Я хочу сделать что-то вроде:
<xsd:schema>
<xsd:all>
<xsd:any processControl="skip" />
<xsd:element name="known1" />
<xsd:element name="known2" />
</xsd:schema>
Этот XSD недопустим, поскольку xsd:any
может отображаться только в xsd:sequence
или xsd:choice
Интересно, как я могу проверить исходный XML-файл с помощью аналогичного простого XSD
Ответ №1:
Вы можете создать xs:choice
из known1, 2 и xs:any
и установить maxOccurs
в unbounded
.
Редактировать: Это по-прежнему обрабатывает только необязательный регистр, но я понял, что вам не обязательно вставлять xs:choice
в xs:sequence
.
Комментарии:
1. а что, если я получу XML без know1 и / или know2? это подтвердит, и это будет неверно
2. итак, known1 и known2 обязательны, но остальные необязательны? в заголовке говорится «Неизвестные по имени необязательные элементы с известными по имени необязательными элементами», поэтому я в замешательстве.
3. Мои извинения, они необязательны. что вы порекомендуете из необязательных элементов? И даже с необязательным элементом, если у меня есть known1 amp; known2 плюс дополнительные элементы (например, unknown1), это не приведет к правильному результату
4. Если использование XML-схемы не является обязательным, вы могли бы попробовать Relax NG, в котором есть концепция чередования и класс имен .
5. К сожалению, это требование
Ответ №2:
Вот рабочая схема, которая позволяет
- свободный порядок между
<known1>
и<known2>
элементами - пропуск
<known1>
или<known2>
(или обоих) - неограниченное количество любых других элементов до, после или между ними
Обратите внимание, что вы должны ограничить элементы, разрешенные <xs:any>
некоторым другим пространством имен, чем <known1>
или <known2>
. В противном случае схема станет однозначной, потому что <xs:any>
также разрешит <known1>
или <known2>
. Еще одна вещь, на которую следует обратить внимание, это то, что здесь нам иногда нужно установить minOccurs
атрибут в <xs:choice>
или <xs:sequence>
, чтобы сохранить детерминированность схемы.
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="skip" />
<xs:choice minOccurs="0">
<xs:sequence>
<xs:element name="known1" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="skip" />
<xs:sequence minOccurs="0">
<xs:element name="known2" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="skip" />
</xs:sequence>
</xs:sequence>
<xs:sequence>
<xs:element name="known2" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="skip" />
<xs:sequence minOccurs="0">
<xs:element name="known1" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="skip" />
</xs:sequence>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Ответ №3:
Короткий ответ: используйте XSD 1.1
Тогда ваше предложение сработает. Более конкретно:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" elementFormDefault="qualified" attributeFormDefault="unqualified" vc:minVersion="1.1">
<xs:element name="root" type="root"/>
<xs:complexType name="root">
<xs:all>
<!-- Required -->
<xs:element name="known1" type="xs:string"/>
<!-- Optional -->
<xs:element name="known2" type="xs:string" minOccurs="0"/>
<xs:element name="known3" type="xs:string" minOccurs="0"/>
<!-- Unknown -->
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
</xs:all>
</xs:complexType>
</xs:schema>