Условное присвоение в XSD1.1 - PullRequest
1 голос
/ 23 января 2020

У меня трудности с написанием схемы в XSD1.1. Структура XML уже определена и используется многими командами, поэтому изменение xml не вариант для меня. Может быть, я не могу объяснить все, что я пытался здесь. XSD так сильно изменился с самого начала. Я просто надеюсь, что некоторые люди смогут ясно понять проблему .. Было бы здорово, если бы кто-то мог поделиться своим способом решения этой проблемы ..

Как выглядит XML (в упрощенном формате)

<Node>
    <Create Type="A">
        <Attr Name="Type1" Val="123"/>
        <Attr Name="Type2" Val="Water"/>
        <Attr Name="Type3" Val="2019-12-01T08:00:00"/>
    </Create>
    <Create Type="B">
        <Attr Name="TypeM" Val="OB123"/>
        <Attr Name="Type2" Val="Fire"/>
        <Attr Name="TypeK" Val="2019-12-01T08:00:00"/>
        <Attr Name="TypeN" Val="11.567"/>   
    </Create>
</Node>

Проблема :

  1. На основе атрибута «Тип» в элементе <<strong> Создать > - Число <<strong> Аттр > Элементы меняются (есть 80 типов). Каждый тип может разрешать указывать c набор дочерних attr . Выше, например, когда Тип = A, он может иметь только 3 дочерних элемента и, в частности, Тип1, Тип2 и Тип3.

  2. На основе значения атрибута «Имя» в Элементе <<strong> Аттр. >, атрибут «Val» может иметь диапазон значений. В Xml, показанном выше, Type2 может иметь {Fire, Water}

  3. На основе значения атрибута "Name" в Элементе <<strong> Attr >, определить тип второго атрибута "Val", который может быть (дата, целое число, строка, число с плавающей точкой и т. д. c)

XSD, который я пытаюсь записать, выглядит примерно так (фактическое XSD и XML огромны) ..

<xs:element name="Node" type="NodeType"/>   

    <xs:complexType name="NodeType">
        <xs:sequence>
            <xs:element name="Create">
                <xs:alternative test="@Type = 'A'" type="AType"/>
                <xs:alternative test="@Type = 'B'" type="BType"/> 
                <xs:alternative type="xs:error"/>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="AType">
        <xs:sequence>
            <xs:element name="Attr">
                <xs:alternative test="@Name = 'Type1'" type="AttrType1"/>
                <xs:alternative test="@Name = 'Type2'" type="AttrType2"/>
                <xs:alternative test="@Name = 'Type3'" type="AttrType3"/>
                <!--<xs:alternative type="xs:error"/>  This line gives error while same line above passes validation-->
            </xs:element> 
        </xs:sequence>
        <xs:attribute name="Type" use="required" type="AllowedTypes"/> <!-- AllowedTypes is an enum of 80 values-->
        <xs:assert test="(@Type = 'A')"/> 
    </xs:complexType>

    <xs:complexType name="AttrType1">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="Val" type="xs:integer"/>
    </xs:complexType>
    <xs:complexType name="AttrType2">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="Val" type="xs:string"/>
        <xs:assert test="(@Val = 'Fire' or @Val='Water')"/> 
    </xs:complexType>
    <xs:complexType name="AttrType3">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="Val" type="xs:dateTime"/>
    </xs:complexType>

<!-- Similarly written for BType -->

Благодаря этому сообщению - Как сделать тип зависимым от значения атрибута, используя условное присвоение типа.

После нескольких дней. Я могу решить 3 проблемы (по одной за раз), указанных выше. Я сталкиваюсь с проблемой, когда пытаюсь объединить все 3 решения в один прекрасный компактный xsd.

Например, когда я пытаюсь решить проблему 3, решение проблемы 1 испорчено.

<Node>
   <Create Type="A">
        <Attr Name="Type1" Val="123"/>
        <Attr Name="Type2" Val="Water"/>
        <Attr Name="TypeZ" Val="2019-12-01T08:00:00"/>
   </Create>
</Node>
    <!-- I want XSD to throw error saying TypeZ is not allowed  -->   

1 Ответ

0 голосов
/ 24 января 2020

Я исправил xsd для решения всех проблемных операторов


<?xml version="1.0"?>
<xs:schema attributeFormDefault="unqualified" 
           elementFormDefault="qualified" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" 
           xmlns:xerces="http://xerces.apache.org"
           vc:minVersion="1.1">

    <xs:element name="Node" type="NodeType"/>   

    <xs:complexType name="NodeType">
        <xs:sequence>
            <xs:element name="Create" maxOccurs="5">
                <xs:alternative test="@Type = 'A'" type="AType"/>
                <xs:alternative test="@Type = 'B'" type="BType"/> 
                <xs:alternative type="xs:error"/>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="AType">
        <xs:sequence>
            <xs:element name="Attr" maxOccurs="3">
                <xs:alternative test="@Name = 'Type1'" type="AttrType1"/>
                <xs:alternative test="@Name = 'Type2'" type="AttrType2"/>
                <xs:alternative test="@Name = 'Type3'" type="AttrType3"/>
                <xs:alternative type="xs:error"/>  
            </xs:element> 
        </xs:sequence>
        <xs:attribute name="Type" use="required" type="xs:string"/>
        <xs:assert test="(@Type = 'A')"/> 
    </xs:complexType>

    <xs:complexType name="AttrType1">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="Val" type="xs:integer"/>
    </xs:complexType>
    <xs:complexType name="AttrType2">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="Val" type="xs:string"/>
        <xs:assert test="(@Val = 'Fire' or @Val = 'Water')"/> 
    </xs:complexType>
    <xs:complexType name="AttrType3">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="Val" type="xs:dateTime"/>
    </xs:complexType>

    <!-- Similarly written for BType -->
    <xs:complexType name="BType">
        <xs:sequence>
            <xs:element name="Attr" maxOccurs="4">
                <xs:alternative test="@Name = 'TypeM'" type="AttrTypeM"/>
                <xs:alternative test="@Name = 'Type2'" type="AttrType2"/>
                <xs:alternative test="@Name = 'TypeK'" type="AttrTypeK"/>
                <xs:alternative test="@Name = 'TypeN'" type="AttrTypeN"/>
                <xs:alternative type="xs:error"/>  
            </xs:element> 
        </xs:sequence>
        <xs:attribute name="Type" use="required" type="xs:string"/>
        <xs:assert test="(@Type = 'B')"/> 
    </xs:complexType>

    <xs:complexType name="AttrTypeM">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="Val" type="xs:string"/>
    </xs:complexType>
    <xs:complexType name="AttrTypeK">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="Val" type="xs:dateTime"/>
    </xs:complexType>
    <xs:complexType name="AttrTypeN">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="Val" type="xs:float"/>
    </xs:complexType>
</xs:schema>

...