Разрешены ли круговые группы схемой XSD?
Для этого XML:
<elem1 xmlns="http://www.fixprotocol.org/ns/fast/t/1.0">
<elem2>
<elem2/>
</elem2>
</elem1>
У меня есть эта схема, которая, кажется, проверяет нормально в отношении службы проверки схемы w3, и схема проверяет вышеупомянутый XML просто отлично. К сожалению, xsd.exe и некоторые другие инструменты сообщают об ошибке. Это верно? Являются ли циклические ссылки на группы запрещенными схемой XML? Спасибо!
Обновление: схема не моя, не могу ее изменить:(
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.fixprotocol.org/ns/fast/t/1.0" xmlns:t="http://www.fixprotocol.org/ns/fast/t/1.0">
<xs:element name="elem1">
<xs:complexType>
<xs:group ref="t:grp1" />
</xs:complexType>
</xs:element>
<xs:group name="grp1">
<xs:sequence>
<xs:group ref="t:grp2" />
</xs:sequence>
</xs:group>
<xs:group name="grp2">
<xs:sequence>
<xs:element minOccurs="0" name="elem2">
<xs:complexType>
<xs:group ref="t:grp1" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:group>
</xs:schema>
4 ответа
Это законная схема. Проблема в том, что xsd пытается обойти все зависимости. Версия MS предварительно обрабатывает схему и расширяет все группы. Из-за циклической зависимости такое расширение будет бесконечным, поэтому оно завершается с ошибкой. В версии Mono возможны два сценария:
- Он пытается пройти по дереву зависимостей и попадает в бесконечный цикл.
- Он пытается расширить все группы и заканчивается бесконечным циклом.
Это только мое предположение. Я никогда не видел реальные исходники Mono XSD.
Этот вопрос связан со многими недавними вопросами, в которых говорится об одной и той же проблеме: круговые группы и файл Microsoft xsd.exe, поэтому я думаю, что на него следует ответить, даже если он довольно "старый".
Путаница вызвана тем, что называется круговой группой. В соответствии с разделом 3.8.6 спецификации XSD:
"Круговые группы не допускаются. То есть внутри {частиц} группы не должно быть на какой-либо глубине частицы, чей {термин} является самой группой".
Исходя из вышеизложенного, ваш пример не является круговой группой, поскольку сама группа не полагается на себя как на частицу. Ваша схема действительна.
Это круговая группа:
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns="http://www.fixprotocol.org/ns/fast/t/1.0" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.fixprotocol.org/ns/fast/t/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="elem1">
<xsd:complexType>
<xsd:group ref="grp1"/>
</xsd:complexType>
</xsd:element>
<xsd:group name="grp1">
<xsd:sequence>
<xsd:choice>
<xsd:group ref="grp1"/>
</xsd:choice>
</xsd:sequence>
</xsd:group>
</xsd:schema>
Нельзя переписать настоящую круговую группу. Однако ваш пример может быть переписан несколькими способами: на схеме ниже показана эквивалентная модель содержимого, основанная на рекурсивных сложных типах.
<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema xmlns="http://www.fixprotocol.org/ns/fast/t/1.0" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.fixprotocol.org/ns/fast/t/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xmlns="">Generated from "Set1" under "Release2"</xsd:documentation>
</xsd:annotation>
<xsd:complexType name="grp1">
<xsd:sequence>
<xsd:element minOccurs="0" name="elem2" type="grp1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="elem1" type="grp1"/>
</xsd:schema>
Также интересно, что следующая схема на самом деле работает с xsd.exe:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema xmlns="http://www.fixprotocol.org/ns/fast/t/1.0" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.fixprotocol.org/ns/fast/t/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xmlns="">Generated from "Set1" under "Release2"</xsd:documentation>
</xsd:annotation>
<xsd:element name="elem1">
<xsd:complexType>
<xsd:group ref="grp1"/>
</xsd:complexType>
</xsd:element>
<xsd:group name="grp1">
<xsd:sequence>
<xsd:element minOccurs="0" name="elem2">
<xsd:complexType>
<xsd:group ref="grp1"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:group>
</xsd:schema>
С точки зрения экземпляра XML все три допустимые схемы эквивалентны.
Возможно, проблема в том, что используемые вами инструменты не поддерживают все возможности, поддерживаемые спецификацией схемы XML. Конечно, xsd.exe не поддерживает все. Спецификация гигантская, и не стоит предоставлять сопоставления из всего, что она поддерживает, в язык программирования, особенно когда некоторые вещи просто не очень хорошо отображаются.
Чтобы обойти это, вы можете попытаться создать набор классов C#, имитирующих xml, который вы хотите сгенерировать, а затем запустить xsd.exe для этих классов, чтобы сгенерировать xsd. Вероятно, есть какая-то другая конструкция XML-схемы, которая поддерживает то, что вы хотите.
Я не знаю о группах, но XSD.exe поддерживает круговые элементы:
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Class1" nillable="true" type="Class1" />
<xs:complexType name="Class1">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Name" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="child" type="Class1" />
</xs:sequence>
</xs:complexType>
</xs:schema>