4

Is there a way to extend XSD elements with custom attributes?

For example, I'd like to do the following in an XSD:

<xs:element name="myElement" type="xs:string" myCustomAttribute="true" />
kjhughes
  • 106,133
  • 27
  • 181
  • 240
Jonathan Bailey
  • 306
  • 2
  • 13

3 Answers3

7

Extending XSD with custom attributes can be accomplished by first defining the custom attributes in your own namespace, as follows:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           targetNamespace="http://www.mycompany.com" 
           elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:attribute name="myAttribute" type="xs:boolean" default="true"/>
</xs:schema>

In this namespace, http://www.mycompany.com, a single attribute named myAttribute is defined, with a type of xs:boolean.

Next, use this namespace in your target schema, as follows:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:mc="http://www.mycompany.com" 
           xsi:schemaLocation="http://www.mycompany.com ./doc.xsd" 
           elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="element1" mc:myAttribute="false"/>
</xs:schema>

In this example, the <schema> element includes attributes that define the custom namespace (xmlns:mc="http://www.mycompany.com"), and the location for the custom schema file (xsi:schemaLocation="http://www.mycompany.com ./doc.xsd").

The target schema contains a single element, "element1", and has the custom attribute myAttribute defined above, with a value of "false". Note that the name of the custom attribute is prefixed with the custom namespace prefix. Also note that if a value of an invalid type is used (example: mc:myAttribute="invalid"), a validation error will be generated.

Credit to @GhislainFourny and @kjhughes for help with this answer.

Jonathan Bailey
  • 306
  • 2
  • 13
2

No, you cannot add your own components to an XSD without confusing XSD processors.

For example, Xerces-J, upon encountering your custom attribute example,

<xs:element name="myElement" type="xs:string" myCustomAttribute="true" />

will respond with the following error:

[Error] try.xsd:3:59: s4s-att-not-allowed: Attribute 'myCustomAttribute' cannot appear in element 'element'.

If you want to augment an XSD, use xsd:annotation/xsd:appinfo or attributes from your own namespace [Credit: @SpatialBridge]:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:myns="http://www.mycompany.com">
  <xs:element name="myElement" myns:myCustomAttribute="true"/>
</xs:schema>
kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • XMLSpy also produces an error. However, qualifying the attribute with a namespace appears to work: ` ` – Jonathan Bailey Mar 29 '16 at 20:46
  • 1
    Yep, that'll work too. Good idea. Answer updated. – kjhughes Mar 29 '16 at 22:46
  • Why is that valid, though? I haven't been able to find documentation that answers that. It doesn't appear as though the custom attribute actually needs to be defined in the custom namespace. If I `import` my own namespace, no error is raised if the attribute isn't defined, or has `type="xs:integer"`, for example. – Jonathan Bailey Mar 29 '16 at 23:02
  • 1
    It's valid because the "Schema for Schemas" explicitly states that you can add attributes in your own namespaces: top level elements and local elements allow extra attributes like so: . Also, the body of the specification states "any attributes with non-schema namespace" right here: https://www.w3.org/TR/xmlschema-1/#declare-element – Ghislain Fourny Mar 30 '16 at 08:07
  • Thanks @GhislainFourny. I still don't understand, however, why I'm not getting validation error on `myns:myCustimAttribute="true"` when I've defined `` in my custom namespace. – Jonathan Bailey Mar 30 '16 at 13:46
  • 1
    You're welcome! There is a typo in the attribute name (i instead of o), so that it doesn't get validated (lax behavior). You need to validate your schema as a regular XML file (not as an XML schema file) against the schema of schemas + your custom namespace schema, both mentioned in xsi:schemaLocation. processContents=lax should trigger a validation if an attribute declaration is in scope. On my side I get an error as expected "The value 'true' of attribute 'myns:myCustomAttribute' on element 'xs:element' is not valid with respect to its type, 'integer'" I hope this helps! – Ghislain Fourny Mar 30 '16 at 16:40
  • @GhislainFournyThanks -- that was a typo in my comment, but it was correct in the file. I believe that the problem that I was having was that I was not declaring the xsi namespace, and I was specifying schemaLocation in an import tag, rather than in the schema tag. The following schema tag allows for validation: `` – Jonathan Bailey Mar 30 '16 at 19:30
0

XBRL is an example of technology that extends XML Schema with its own custom attributes.

The following example is taken directly from the XBRL 2.1 specification. xbrli:balance and xbrli:periodType are added by XBRL on top of XML Schema.

<element
  id="a2"
  name="fixedAssets"
  xbrli:balance="debit"
  xbrli:periodType="instant"
  type="xbrli:monetaryItemType"
  substitutionGroup="xbrli:item"/>

As stated in kjhughes's answer though, you need to use your own namespace (in this case the xbrli prefix is bound with http://www.xbrl.org/2003/instance).

Ghislain Fourny
  • 6,971
  • 1
  • 30
  • 37