Search code examples
javaxmlspringxsdxml-validation

One XSD for both whole document and fragment?


I wish to create a grammar able to validate both a full XML document and a fragment of it.

I have a set of documents aggregate in a “batch”. Each document has a set of meta-data:

<batch>
    <document>
        <metadata1 />
        <metadata2 />
        <metadata3 />
    </document>
    <document>
        <metadata1 />
        <metadata2 />
        <metadata3 />
    </document>
</batch>

My SpringBatch process splits the batch in documents (with StaxEventItemReader) I wish to validate a sub XML representing a single document:

<document>
    <metadata1 />
    <metadata2 />
    <metadata3 />
</document>

I read here that I can’t use partial XSD to validate XML.

However, is there is a way, while avoiding duplication, to validate with two XSDs, where one would validate the fragment, and the other would validate the batch?


Solution

  • You can achieve your goal with a single XSD by specifying multiple possible root elements:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
      <xs:element name="batch">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="document" maxOccurs="unbounded"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    
      <xs:element name="document">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="metadata1" type="xs:string" />
            <xs:element name="metadata2" type="xs:string" />
            <xs:element name="metadata3" type="xs:string" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    
    </xs:schema>
    

    This way documents may have either a batch or a document root element, and there is no definition duplication.