1
votes

I Need to validate several XML-Files with one XSD-File... The XML-Files can occur in several forms... and I need to catch all cases.

XML1:

<BusinessRule>
   ABC
</BusinessRule>

XML2:

<BusinessRule>
<Case number="1">
  <Lookup class="type">
     <LkpColumn>column1</LkpColumn>
     <LkpText>someText1</LkpText>
  </Lookup>
</Case>
<Case number="2">
  <Lookup class="type">
     <LkpColumn>column2</LkpColumn>
     <LkpText>someText2</LkpText>
  </Lookup>
</Case>
<Case number="3">
  <Lookup class="type">
     <LkpColumn>column3</LkpColumn>
     <LkpText>someText3</LkpText>
  </Lookup>
</Case>
</BusinessRule>

XML3:

<BusinessRule>
   <Lookup class="type">    
      <LkpColumn>column</LkpColumn>
      <LkpText>someText</LkpText>
   </Lookup>
</BusinessRule>

XML4:

<BusinessRule>
   <If>condition1</If>
   <Then>then_bough1</Then>
   <Else>
       <If>condition2</If>
       <Then>then_bough2</Then>
       <Else>else1</Else>
   </Else>
</BusinessRule>

MY XSD:

<!-- ... -->
<!-- BusinessRule -->
<xs:complexType name="BusinessRuleType" mixed="true">
    <!-- I NEED THIS PART, BUT IT DOESN'T WORK! -->
    <!--
    <xs:simpleContent>
        <xs:restriction base="xs:string">
            <xs:pattern value="[a-zA-Z][a-zA-Z][a-zA-Z]"/>
        </xs:restriction>
    </xs:simpleContent> 
    -->
    <xs:choice>
        <xs:element name="Case" type="CaseType" minOccurs="0" maxOccurs="unbounded" />
        <xs:element name="Lookup" type="LookupType"/>
        <xs:sequence>
            <xs:element name="If"/>
            <xs:element name="Then"/>
            <xs:element name="Else"/>
        </xs:sequence>
    </xs:choice>
</xs:complexType>

<!-- case -->
<xs:complexType name="CaseType" mixed="true">
    <xs:sequence>
        <xs:element name="Lookup" type="LookupType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="number" type="xs:positiveInteger" use="required"/>
</xs:complexType>

<!-- LookUp -->
<!-- ... -->

I think I understood to cover XML2 - XML4... But I also need to check the Content of XML1 with some "Restriction"-Tags... Is this possible?

Thanks for the help!

1

1 Answers

1
votes

Actually, by virtue of using mixed="true" your XML1 case will already be valid, but note that each of your cases will also allow the sprinkling of text between the elements of the BusinessRule content. I'm guessing you probably don't want this. If not, remove mixed="true" and redesign your XML1 case to use a wrapping element, say, Symbol:

<xs:choice>
  <xs:element name="Symbol">
    <xs:simpleType>
      <xs:restriction base="xs:string">
        <xs:pattern value="[a-zA-Z][a-zA-Z][a-zA-Z]"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:element>
  <xs:element name="Case" type="CaseType" minOccurs="0" maxOccurs="unbounded" />
  <xs:element name="Lookup" type="LookupType"/>
  <xs:sequence>
    <xs:element name="If"/>
    <xs:element name="Then"/>
    <xs:element name="Else"/>
  </xs:sequence>
</xs:choice>

You will then be able to restrict the content for the XML1 case (provided the content is wrapped in a dedicated element). Using mixed="true", it is not possible to restrict the text further using XSD 1.0. (Schematron or XSD 1.1's xs:assert can layer additional constraints on mixed content -- thanks to @Abel for the reminder.)