Определение рекурсивных алгебраических типов данных в XML XSD
-
22-09-2019 - |
Вопрос
Представьте, что у меня есть рекурсивный алгебраический тип данных вот так (синтаксис Haskell):
data Expr = Zero
| One
| Add Expr Expr
| Mul Expr Expr
Я хотел бы представить это в XML и мне нужна для этого схема XSD.
Я понял, как добиться этого синтаксиса:
<Expr>
<Add>
<Expr>
<Zero/>
</Expr>
<Expr>
<Mul>
<Expr>
<One/>
</Expr>
<Expr>
<Add>
<Expr>
<One/>
</Expr>
<Expr>
<One/>
</Expr>
</Add>
</Expr>
</Mul>
</Expr>
</Add>
</Expr>
с этой схемой:
<xs:complexType name="Expr">
<xs:choice minOccurs="1" maxOccurs="1">
<xs:element minOccurs="1" maxOccurs="1" name="Zero" type="Zero" />
<xs:element minOccurs="1" maxOccurs="1" name="One" type="One" />
<xs:element minOccurs="1" maxOccurs="1" name="Add" type="Add" />
<xs:element minOccurs="1" maxOccurs="1" name="Mul" type="Mul" />
</xs:choice>
</xs:complexType>
<xs:complexType name="Zero">
<xs:sequence>
</xs:sequence>
</xs:complexType>
<xs:complexType name="One">
<xs:sequence>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Add">
<xs:sequence>
<xs:element minOccurs="2" maxOccurs="2" name="Expr" type="Expr" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Mul">
<xs:sequence>
<xs:element minOccurs="2" maxOccurs="2" name="Expr" type="Expr" />
</xs:sequence>
</xs:complexType>
Но что мне действительно нужно, так это синтаксис:
<Add>
<Zero/>
<Mul>
<One/>
<Add>
<One/>
<One/>
</Add>
</Mul>
</Add>
Это возможно?
Спасибо!
Решение
Используйте группы замены:
<xs:element name="Expr" abstract="true"/>
<xs:element name="Zero" substitutionGroup="Expr">
<xs:complexType/>
</xs:element>
<xs:element name="One" substitutionGroup="Expr">
<xs:complexType/>
</xs:element>
<xs:element name="Add" substitutionGroup="Expr">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="2" maxOccurs="2" ref="Expr" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Mul" substitutionGroup="Expr">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="2" maxOccurs="2" ref="Expr" />
</xs:sequence>
</xs:complexType>
</xs:element>
Не связан с StackOverflow