-->

XSD: How to create a complexType where elements ca

2019-08-20 10:23发布

问题:

I have a complex type like:

<xs:complexType name="blocks">
<xs:sequence>
  <xs:element name="BlockA" type="blockA" minOccurs="1" maxOccurs="unbounded"/>
  <xs:element name="BlockB" type="blockB" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="Name" type="xs:string" use="required" />
<xs:attribute name="Use" type="xs:boolean" use="required" /></xs:complexType>

but it is not configured how I would like.

I want it so that

  1. Elements 'BlockA' and 'BlockB' can be in ANY order
  2. BlockA has to occur at least 1 time.
  3. BlockB can occur 0 or more times.

The XSD order indicators 'sequence' and 'choice' don't seem to provide such options.

Please, is there a way to achieve what I am looking for?

Many thanks in advance.

PS Apologies for the formatting, I just could not get it to wrap and indent correctly.

回答1:

If you need to do this in XSD 1.0 I believe it can be expressed as

sequence
  element name=BlockB min=0 max=unbounded
  element name=BlockA min=1 max=1
  choice min=0 max=unbounded
    element name=BlockA min=1 max=1
    element name=BlockB min=1 max=1


回答2:

I tested your code and a solution is replacing the xs:sequence by xs:all. Unfortunately this solution works only in XSD-1.1, because XSD-1.0 has the restriction that maxOccurs can only be 0 or 1 (see comments below).

<xs:complexType name="blocks">
    <xs:all>
        <xs:element name="BlockA" type="blockA" minOccurs="1" maxOccurs="unbounded"/>
        <xs:element name="BlockB" type="blockB" minOccurs="0" maxOccurs="unbounded" />
    </xs:all>
    <xs:attribute name="Name" type="xs:string" use="required" />
    <xs:attribute name="Use" type="xs:boolean" use="required" />
</xs:complexType>

This has worked in my example code.


EDIT: I used the following XSD as a test-case:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema
  elementFormDefault="unqualified"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="root" type="blocks" />

    <xs:complexType name="blocks">
        <xs:all>
            <xs:element name="BlockA" type="blockA" minOccurs="1" maxOccurs="unbounded"/>
            <xs:element name="BlockB" type="blockB" minOccurs="0" maxOccurs="unbounded" />
        </xs:all>
        <xs:attribute name="Name" type="xs:string" use="required" />
        <xs:attribute name="Use" type="xs:boolean" use="required" />
    </xs:complexType>

    <xs:simpleType name="blockA">
        <xs:restriction base="xs:string" />
    </xs:simpleType>

    <xs:simpleType name="blockB">
        <xs:restriction base="xs:string" />
    </xs:simpleType>

</xs:schema>

And my example code samples were the following:

    • BlockA >= 1
    • BlockB >= 1

    for this code:

    <root Name="ThisIsAName" Use="true">
        <BlockB>DEF</BlockB>    
        <BlockA>ABC</BlockA>
        <BlockA>ABC</BlockA>
        <BlockA>ABC</BlockA>
        <BlockA>ABC</BlockA>
        <BlockB>DEF</BlockB>    
    </root>
    

    ===> VALID!!!

    • BlockA >= 1
    • BlockB = 0

    for this code:

    <root Name="ThisIsAName" Use="true">
        <BlockA>ABC</BlockA>   
        <BlockA>ABC</BlockA>   
    </root>
    

    ===> VALID!!!

    • BlockA = 0
    • BlockB >= 1

    for this code:

    <root Name="ThisIsAName" Use="true">
        <BlockB>DEF</BlockB>    
        <BlockB>DEF</BlockB>    
    </root>
    

    ===> FAIL!!!

    • BlockA = 0
    • BlockB = 0

    for this code:

    <root Name="ThisIsAName" Use="true">
    </root>
    

    ===> FAIL!!!

So with XSD-1.1 everything does work.