Title: XSD for complex XML structure
Tags: xml;xsd;xml-parsing;xsd-validation
Question: I have a rather complex XML structure I am trying to validate and I can't seem to come up with a XSD structure that would allow me to express the following:

```<foo fooAttribute1="..." fooAttribute2="..." ...&gt;
  <bar1 id="1" ... /&gt;
  <bar1 id="2" ... /&gt;
  <bar2 id="1" ... /&gt;
  <bar2 id="2" ... /&gt;
  <![MyFormattedTextGoesHere[foo text goes here]]&gt;
</foo&gt;
```

So, I want to have a ```foo``` which can contain 


attributes
0..* ```bar1``` elements
0..* ```bar2``` elements
formatted text (e.g. starting with ```<![MyFormattedTextGoesHere[``` and ending with ```]]&gt;```


On a related note: can I also validate attribute values like so: 
```<xml someAttribute=$... /&gt;``` (has to start with a ```$```)?  

What I currently have is

```<xs:element name="foo" minOccurs="0" maxOccurs="unbounded"&gt;
  <xs:complexType mixed="true"&gt;
    <xs:sequence&gt;
      <xs:element name="bar1" minOccurs="0" maxOccurs="unbounded"&gt;
        <xs:complexType&gt;
          <xs:attribute name="id" form="unqualified" type="xs:string" /&gt;
          <xs:attribute name="..." form="unqualified" type="xs:string" /&gt;
        </xs:complexType&gt;
      </xs:element&gt;
      <xs:element name="bar2" minOccurs="0" maxOccurs="unbounded"&gt;
        <xs:complexType&gt;
          <xs:attribute name="id" form="unqualified" type="xs:string" /&gt;
          <xs:attribute name="..." form="unqualified" type="xs:string" /&gt;
        </xs:complexType&gt;
      </xs:element&gt;
    </xs:sequence&gt;
    <xs:attribute name="fooAttribute1" form="unqualified" type="xs:string"/&gt;
    <xs:attribute name="fooAttribute2" form="unqualified" type="xs:string"/&gt;
    <xs:attribute name="..." form="unqualified" type="xs:string" /&gt;
    <!-- accept/validate text here? --&gt;
  </xs:complexType&gt;
  <!-- or here? --&gt;
</xs:element&gt;
```

Comment: Edited my question to show my current XSD structure. I tried to add simpleContent but couldn't mix it with the child elements `bar1`, `bar2`, I think

Here is the accepted answer: The XML above is not well-formed because of ```<!``` followed by general text. What is meant here may be a CDATA section, like so:

```<?xml version="1.0" encoding="UTF-8"?&gt;
<foo fooAttribute1="$..." fooAttribute2="..." &gt;
   <bar1 id="1" /&gt;
   <bar1 id="2" /&gt;
   <bar2 id="1" /&gt;
   <bar2 id="2" /&gt;
   <![CDATA[MyFormattedTextGoesHere[foo text goes here]]&gt;
</foo&gt;
```

A good starting point for a schema against which the above XML is valid is this:

```<?xml version="1.0" encoding="UTF-8"?&gt;
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"&gt;
    <xs:simpleType name="beginswithdollar"&gt;
        <xs:restriction base="xs:string"&gt;
            <xs:pattern value="\$.*"/&gt;
        </xs:restriction&gt;
    </xs:simpleType&gt;
    <xs:element name="foo"&gt;
        <xs:complexType mixed="true"&gt;
            <xs:sequence&gt;
                <xs:element name="bar1" minOccurs="0" maxOccurs="unbounded"&gt;
                    <xs:complexType&gt;
                        <xs:sequence/&gt;
                        <xs:attribute name="id" type="xs:string"/&gt;
                    </xs:complexType&gt;
                </xs:element&gt;
                <xs:element name="bar2"  minOccurs="0" maxOccurs="unbounded"&gt;
                    <xs:complexType&gt;
                        <xs:sequence/&gt;
                        <xs:attribute name="id" type="xs:string"/&gt;
                    </xs:complexType&gt;
                </xs:element&gt;
            </xs:sequence&gt;
            <xs:attribute name="fooAttribute1" type="beginswithdollar"/&gt;
            <xs:anyAttribute processContents="lax"/&gt;
        </xs:complexType&gt;
    </xs:element&gt;
</xs:schema&gt;
```

A few things are not supported by XML Schema though:


Whether text is in CDATA sections or not is not visible by XML Schema. CDATA sections are used to avoid escaping special characters.
Complex types can be mixed-content or not. If mixed-content, it can not be controlled where the text appears or what its type is: it could also appear before or between ```bar*``` elements.
Attributes can be allowed with no restriction with ```xs:anyAttribute```, but it is not possible to restrict their type in general. In the above schema, for example, the attribute ```fooAttribute1``` must start with a dollar, while any other attributes are allowed with no restriction.


If XML Schema 1.1 is supported, there is also the ```assert``` feature that allows to express user-defined constraints. This may be a way to further restrict validity of instances in a tailored way beyond what other XML Schema components can do.

Comment for this answer: Thanks so far; one more question, though: Is there a way to check if there is a CDATA section present?
Comment for this answer: @vonludi No, as far as XSD is concerned it is irrelevant whether the text is in a CDATA section or not (just as it is irrelevant if `E` is written as `&#x45;`)


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 1, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2017:00:09/05/17', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<xml><xsd><xml-parsing><xsd-validation>', 'Title': 'XSD for complex XML structure', 'ViewCount': 249, 'id': 46048516, 'user_AboutMe': '', 'user_AccountId': 5176181.0, 'user_DisplayName': 'vonludi', 'user_Reputation': 409.0, 'user_Views': 61.0, 'user_id': 4143232.0}}