2

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?

Community
  • 1
  • 1
Sasha
  • 3,405
  • 4
  • 19
  • 21
  • Argh - the answer is in the question. The complexType defined above DOES work, there was a problem with my XML file. – Sasha Feb 11 '15 at 20:37

3 Answers3

1

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>
kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • Odd - when I try this, it still considers bad text as valid (I didn't try the other invalid case). Does it matter that the DEPRECATED element is itself in a sequence belonging to another complex type? Will add details to the original question... – Sasha Feb 11 '15 at 20:16
  • No, that should not matter. Please provide ***exact*** XSD and XML and error message if you're still having trouble, because being in a sequence, or being defined anonymously or explicitly should not matter. Thanks. – kjhughes Feb 11 '15 at 20:25
  • Thank you. I found the problem - the deprecated element in my file (the one I expected to be invalid) was the child of another element, not a "property" element. – Sasha Feb 11 '15 at 20:39
0

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>
Mike Barlotta
  • 715
  • 4
  • 16
  • Sorry. did not mean to offend. The original question seemed to be trying to add a restriction to the attribute so was trying to show how that might be done and put the whole thing in full context. – Mike Barlotta Feb 11 '15 at 20:14
  • looks like the original comment was deleted. hope the answer helps – Mike Barlotta Feb 11 '15 at 20:24
  • BTW: I tested with your nested complexTypes and got it to work. How are you testing the validation? – Mike Barlotta Feb 11 '15 at 20:29
  • You're right, it does work. The deprecated element in my file (the one I expected to be invalid) was the child of another element, not a "property" element. #facepalm And I saw the comment you're referring to before it got deleted. Wasn't mine :). Cheers. – Sasha Feb 11 '15 at 20:41
0

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>