2
votes

I am trying to create an XSD for validating an XML file, and several elements need to have attributes but no text.

E.g. This should be considered valid:

<DEPRECATED value="blah"/>

These are invalid:

<DEPRECATED>blah</DEPRECATED>
<DEPRECATED value="blah">bad text</DEPRECATED>

I tried declaring a complex empty element as described here, but either I'm interpreting the example incorrectly or the example itself is wrong (see error below):

<xs:element name="DEPRECATED" type="stringValue" minOccurs="0" maxOccurs="1"/>

<xs:complexType name="stringValue">
        <xs:complexContent>
            <xs:restriction base="xs:integer">
                <xs:attribute name="value" type="xs:string"/>
            </xs:restriction>
        </xs:complexContent>
</xs:complexType>

Error: Complex Type Definition Representation Error for type 'stringValue'. When is used, the base type must be a complexType. 'integer' is a simpleType.

I also tried defining the complexType this way:

<xs:complexType name="stringValue">
    <xs:attribute name="value" type="xs:string"/>
</xs:complexType>

But that considers the invalid examples above as valid. [EDIT: Correction, the above does work.]

I've also played around with the answers to similar questions (Define an XML element that must be empty and has no attributes, Prevent Empty Elements in XML via XSD) but no luck.

How do I validate that an element has attributes, but NO text?

3
Argh - the answer is in the question. The complexType defined above DOES work, there was a problem with my XML file.Sasha

3 Answers

1
votes

This XML will be valid

<DEPRECATED value="blah"/>

and this XML

<DEPRECATED>blah</DEPRECATED>

and this XML

<DEPRECATED value="blah">bad text</DEPRECATED>

will be invalid using this XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="DEPRECATED">
    <xs:complexType>
      <xs:attribute name="value"/>
    </xs:complexType>
  </xs:element>

</xs:schema>
0
votes

I think you are after something like this

<xs:schema elementFormDefault="qualified" version="1.0"
    targetNamespace="stackoverflow" xmlns:tns="stackoverflow"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="Test">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="DEPRECATED" type="tns:deprecatedType" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="deprecatedType">
        <xs:attribute name="number" />
    </xs:complexType>
</xs:schema>

This XML document was valid

<sf:Test xmlns:sf="stackoverflow"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="stackoverflow test.xsd">
    <sf:DEPRECATED number="123"/>
</sf:Test>

This XML document was invalid

<sf:Test xmlns:sf="stackoverflow"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="stackoverflow test.xsd">
    <sf:DEPRECATED number="123">TEST</sf:DEPRECATED>
</sf:Test>

If you want to restrict the attribute you might need something like this:

<xs:complexType name="deprecatedType">
    <xs:attribute name="number">
        <xs:simpleType>
            <xs:restriction base="xs:string" />
        </xs:simpleType>
    </xs:attribute>
</xs:complexType>
0
votes

Try this:

  <xsd:simpleType name="EmptyType">
    <xsd:restriction base="xsd:string">
      <xsd:length value="0" />
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:complexType name="DeprecatedType">
    <xsd:simpleContent>
      <xsd:extension base="EmptyType">
        <xsd:attribute name="value" type="xsd:string" />
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>