Схема XML для Tagged Union
У меня есть документ XML, который включает в себя повторяющиеся серии адресов, фактическое содержание которых зависит от значения включенного перечисления. Я полагаю, это тип "тегового союза" [или "дискриминационного союза"?]:
{
<AddressList>
<Address>
<AddressType type="addressEnum" fixed="CanadianAddress"/>
<AddressValue>
<Street type="textstring">123 Yonge Street</Street>
<Province type="provinceEnum" value="Ontario"/>
<PostalCode type="postalCodeType" value="M1N 2O3"/>
</AddressValue>
</Address>
<Address>
<AddressType type="addressEnum" fixed="USAddress"/>
<AddressValue>
<Street type="textstring">456 Front Street</Street>
<State type="stateEnum" value="New York"/>
<ZipCode type="zipCodeType" value="12345"/>
</AddressValue>
</Address>
</AddressList>
}
Мне неясно, как выразить XML-схему [т.е. XSD] для вышеуказанного XML. Нужен ли мне пустой AddressType, который будет расширяться как CanadianAddressType, так и USAddressType? Если бы у меня было 50 AddressTypes, потребовалось бы мне 50 таких расширений?
ПРИМЕЧАНИЕ. Если это не очевидно, элементы адреса USA не могут появляться после перечисления CanadianAddress. Аналогично, элементы CanadianAddress не могут появляться после перечисления USAddress.
1 ответ
Это возможно при использовании альтернативных компонентов XSD 1.1. Тогда вы сможете применить тип для <AddressValue>
узел зависит от fixed
значение атрибута AddressType
элемент, так
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/XMLSchema.xsd"
xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
vc:minVersion="1.1">
<xs:element name="AddressList" >
<xs:complexType>
<xs:sequence>
<xs:element name="Address" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="AddressType" type="AddressTypeTag"/>
<xs:element name="AddressValue" type="USAddressValue">
<xs:alternative test="../AddressType/@fixed='CanadianAddress'" type="CanadianAddressValue"/>
<xs:alternative test="../AddressType/@fixed='USAddress'" type="USAddressValue"/>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="CanadianAddressValue">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="Street" type="StreetValue"/>
<xs:element name="Province" type="TypeAndValue"/>
<xs:element name="PostalCode" type="TypeAndValue"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="USAddressValue">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="Street" type="StreetValue"/>
<xs:element name="State" type="TypeAndValue"/>
<xs:element name="ZipCode" type="TypeAndValue"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="StreetValue">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="type" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="TypeAndValue">
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="value" type="xs:string"/>
</xs:complexType>
<xs:complexType name="AddressTypeTag">
<xs:attribute name="type" fixed="addressEnum" type="xs:string" />
<xs:attribute name="fixed" >
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="CanadianAddress"></xs:enumeration>
<xs:enumeration value="USAddress"></xs:enumeration>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:schema>