Search code examples
xmlxsdxsd-validationxml-validation

XML instance prohibiting elements not defined in the schema


I am creating a XML schema for provide feedback to reporters of data. How do I prevent another party creating an file based on the schema using elements not defined in the schema?

Using the following schema:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="logical-model" 
           targetNamespace="logical-model"
           elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="logicalModelErrors">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="reportSetAspects"/>
            <xs:element name="errorsPerEntity"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="reportSetAspects">
    <xs:complexType>
        <xs:sequence >
            <xs:element name="aspect" minOccurs="1" maxOccurs="2"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="aspect">
    <xs:complexType>
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="name" use="required"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
</xs:element>
</xs:schema>

My instance is:

<?xml version="1.0" encoding="UTF-8"?>
<logicalModelErrors xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="logical-model" xsi:schemaLocation="logical-model LogMod.xsd">
  <reportSetAspects>
    <aspect name="bank identifier">BANK-ABDC1234</aspect>
    <aspect name="reporting reference date">2018-04-01</aspect>
    <abc>dd</abc>
  </reportSetAspects>
  <def>sss</def>
</logicalModelErrors>

If I validate this file in XMLSpy I get an error for def but not abc. Error message:

Element <def> is not allowed under element <logicalModelErrors>.
Reason: No more elements expected.
Error location: logicalModelErrors / def

Can somebody tell me why?


Solution

  • Change

            <xs:element name="reportSetAspects"/>
    

    to

            <xs:element ref="reportSetAspects"/>
    

    in order to use your global declaration of reportSetAspects. Otherwise, a new local declaration of reportSetAspects is used, and any content model is allowed in it because it specifies nothing more than the element name.

    Other notes:

    • aspect suffers a similar problem.
    • errorsPerEntity currently allows any content for similar reasons.
    • In your XSD, <xml version="1.0" encoding="UTF-8"?> should be <?xml version="1.0" encoding="UTF-8"?> [note missing ?].