svoop
svoop

Reputation: 3454

Extend an XML schema (AIXM) to allow arbitrary elements

I'm struggling with any elements in a XML schema, here's the (abridged) type definition – a part of AIXM:

<xsd:element name="Ase" type="AirspaceType"/>

<xsd:complexType name="AirspaceType">
  <xsd:annotation>
    <xsd:documentation>Airspace</xsd:documentation>
  </xsd:annotation>
  <xsd:sequence>
    <xsd:element name="txtName" type="txtName" minOccurs="0">
      <xsd:annotation>
        <xsd:documentation>Name (as published in AIP)</xsd:documentation>
      </xsd:annotation>
    </xsd:element>
  </xsd:sequence>
  <xsd:attribute ref="source"/>
</xsd:complexType>

The following is therefore schema valid:

<Ase source="foobar">
  <txtName>Some Airspace</txtName>
</Ase>

I'd like to extend this schema to allow for any number of arbitrary elements following the last element of the sequence provided these elements begin with an underscore, for instance:

<Ase source="foobar">
  <txtName>Some Airspace</txtName>
  <_test>This should be valid</_test>
</Ase>

And:

<Ase source="foobar">
  <txtName>Some Airspace</txtName>
  <test>This should NOT valid since the element name doesn't begin with an underscore</test>
</Ase>

I've tried a couple of things, even asked AI for help, but the best I could come up with is:

<xsd:element name="Ase" type="AirspaceType"/>

<xsd:complexType name="AirspaceType">
  <xsd:annotation>
    <xsd:documentation>Airspace</xsd:documentation>
  </xsd:annotation>
  <xsd:sequence>
    <xsd:element name="txtName" type="txtName" minOccurs="0">
      <xsd:annotation>
        <xsd:documentation>Name (as published in AIP)</xsd:documentation>
      </xsd:annotation>
    </xsd:element>
  </xsd:sequence>
  <xsd:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded">
    <xsd:annotation>
      <xsd:documentation>Unofficial extension</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:anyName">
      <xsd:pattern value="_.*"/>
    </xsd:restriction>
  </xsd:any>
  <xsd:attribute ref="source"/>
</xsd:complexType>

However, such a schema is invalid:

element any: Schemas validity error : Element '{http://www.w3.org/2001/XMLSchema}any': This element is not expected. Expected is one of ( {http://www.w3.org/2001/XMLSchema}attribute, {http://www.w3.org/2001/XMLSchema}attributeGroup, {http://www.w3.org/2001/XMLSchema}anyAttribute ).

Is it even possible to extend the schema in this way and if so, what am I doing wrong?

Thanks a bunch!

Upvotes: 0

Views: 66

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167696

With the current version 1.1 of the schema language (supported by Xerces Java, Saxon EE, https://pypi.org/project/xmlschema/, and I think also Altova) you can write an assertion in the form of e.g.

<xs:complexType name="AirspaceType">
    <xs:annotation>
        <xs:documentation>Airspace</xs:documentation>
    </xs:annotation>
    <xs:sequence>
        <xs:element name="txtName" type="xs:string" minOccurs="0">
            <xs:annotation>
                <xs:documentation>Name (as published in AIP)</xs:documentation>
            </xs:annotation>
        </xs:element>
        <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded">
            <xs:annotation>
                <xs:documentation>Unofficial extension</xs:documentation>
            </xs:annotation>
        </xs:any>
    </xs:sequence>

    <xs:attribute name="source" type="xs:string"/>
    
    <xs:assert id="name_prefix" test="every $child in *[not(self::txtName)] satisfies starts-with(local-name($child), '_')"></xs:assert>
</xs:complexType>

That would make your sample with _test valid and the one with test invalid.

Whether that is a good idea in the world of XML and schemas to use assertions that way is another question; I would think that most people want the grammar to clearly define the types and names of elements and not to put some syntax rules for names into assertions; but if that is your requirement then I think an assertion is likely the (only) way the schema language allows you to express that.

Of course the other error in your posted sample is simply the placement of xs:any outside of the xs:sequence.

Upvotes: 0

Related Questions