Xerces reports error when giving attribute to top-level element - xsd

I have the following schema which works fine:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="bindings">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="bind">
<xs:complexType>
<xs:attribute name="trigger" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute> <!-- trigger -->
<xs:attribute name="command" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute> <!-- command -->
</xs:complexType>
</xs:element> <!-- bind -->
</xs:sequence>
</xs:complexType>
</xs:element> <!-- bindings -->
</xs:schema>
However, when I try to define an attribute for the top level bindings element, I get an error no matter where I place the attribute code. What am I missing or doing wrong?
EDIT: It looks like there's some problem with either my Java XML code or Xerces. If I change the XSD to give the top-level element the optional "parent" attribute, Xerves gives me the error "Problem: schema_reference.4: Failed to read schema document 'null', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>." However, if I give the attribute any name //other// than "parent", it reports Attribute 'parent' is not allowed to appear in element 'bindings'., just as you'd expect.
My Java code regarding XSD and Xerces is:
bindingsDocumentBuilderFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilderFactory bdbf = bindingsDocumentBuilderFactory;
bdbf.setValidating(true);
// I get the input stream here as "is"
bdbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
bdbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", is);
EDIT 2:
The XML file which is being validated:
<bindings parent="game/movement">
<bind trigger="i" command="INVENTORY"/>
</bindings>

This works (see attribute named code):
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="bindings">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="bind">
<xs:complexType>
<xs:attribute name="trigger" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<!-- trigger -->
<xs:attribute name="command" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<!-- command -->
</xs:complexType>
</xs:element>
<!-- bind -->
</xs:sequence>
<xs:attribute name="code"/>
</xs:complexType>
</xs:element>
<!-- bindings -->
</xs:schema>

Related

XSD complexType with element AND simpleContent

Working with XML 1.1 in Oxygen XML Editor version 23.1.
Originally I wandted to make an xsd schema that can have a complexType-element with a child-element, an extension and a bunch of attributes. A first possible solution I was able to get here but figured out it didn't fit to my problem, because the child-element itself consists of several elements and attributes which makes the original approach invalid, causing the error message: "The content type of a derived type and that of its base must both be mixed or both be element-only. Type 'complexTypeContent' is mixed, but its base type is not".
To my problem itself: The aim is for the child-element random to only be used when the attribute until has the value 'random'. So in the end a XML-file like this should be valid:
<instruction>
<type repeat='1' until='random'><random start='1' end='6'/>Dice Roll</type>
</instruction>
Instead - if the attribute until has not the value "random" - the element random must not be allowed. So something like this should be forbidden:
<instruction>
<type repeat='1' until='2'><random start='1' end='6'/>Dice Roll</type>
</instruction>
With help from here I was able to modify my xsd-scheme to something like this. But as already stated, it doesn't compile without an error message:
<xs:element name="root">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="instruction" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="type">
<xs:alternative test="#until = 'random'" type="complexTypeContent"/>
<xs:alternative type="simpleTypeContent"/>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="complexTypeContent" mixed="true">
<xs:complexContent>
<xs:extension base="simpleTypeContent">
<xs:sequence>
<xs:element name="random" type="random" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="random">
<xs:attribute name="start">
<xs:simpleType>
<xs:restriction base="xs:integer"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="end">
<xs:simpleType>
<xs:restriction base="xs:integer"/>
</xs:simpleType>
</xs:attribute>
<xs:assert test="#start le #end"/>
</xs:complexType>
<xs:complexType name="simpleTypeContent" mixed="true">
<xs:simpleContent>
<xs:extension base="type2">
<xs:attribute name="until">
<xs:simpleType>
<xs:union memberTypes="type2 annotation xs:integer until"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="condition">
<xs:simpleType>
<xs:union memberTypes="type2 annotation extended"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="repeat" type='xs:integer'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="type2">
<xs:restriction base="xs:string">
<xs:enumeration value="Dice Roll"/>
<xs:enumeration value="Wait"/>
<xs:enumeration value="Repeat"/>
<xs:enumeration value="Double Roll"/>
<xs:enumeration value="Instruction"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="until">
<xs:restriction base="xs:string">
<xs:enumeration value="end"/>
<xs:enumeration value="random"/>
<xs:enumeration value="Instruction"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="annotation">
<xs:restriction base="xs:string">
<xs:enumeration value="rolltwice"/>
<xs:enumeration value="halfcount"/>
<xs:enumeration value="doublecount"/>
<xs:enumeration value="roll-"/>
<xs:enumeration value="roll+"/>
<xs:enumeration value="numberChange"/>
<xs:enumeration value="NoNumberChange"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="extended">
<xs:restriction base="xs:string">
<xs:enumeration value="noRolling"/>
<xs:enumeration value="noEven"/>
<xs:enumeration value="noUneven"/>
<xs:enumeration value="stopped"/>
</xs:restriction>
</xs:simpleType>
The error messages I had now all imply that this solution is invalid because of the not mixed content of simpleTypeContent or because it has simpleContent which cannot be derived from the complex content of complexTypeContent. So, how do I get it working? I cannot figure out any working solution for the problem I am facing.
As far as I understand, XSD (not even 1.1) doesn't offer a way to restrict the mixed content text to some simple type, so the only way, if you really need that single element together with a certain list of values seems to be an assertion; that means, unfortunately, you need to duplicate the values you also want for an attribute.
So some (slightly adapted, see my comment about the `#until = 'random' check) sample schema would be
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
<xs:element name="root">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="instruction" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="type">
<xs:alternative test="#until = 'random'" type="complexTypeContent"/>
<xs:alternative type="simpleTypeContent"/>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="complexTypeContent" mixed="true">
<xs:complexContent>
<xs:extension base="simpleTypeContent">
<xs:sequence>
<xs:element name="random" type="random" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="random">
<xs:attribute name="start">
<xs:simpleType>
<xs:restriction base="xs:integer"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="end">
<xs:simpleType>
<xs:restriction base="xs:integer"/>
</xs:simpleType>
</xs:attribute>
<xs:assert test="#start le #end"/>
</xs:complexType>
<xs:complexType name="simpleTypeContent" mixed="true">
<xs:attribute name="until">
<xs:simpleType>
<xs:union memberTypes="type2 annotation xs:integer until"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="condition">
<xs:simpleType>
<xs:union memberTypes="type2 annotation extended"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="repeat" type='xs:integer'/>
<xs:assert test=". = ('Dice Roll', 'Wait', 'Repeat', 'Double Roll', 'Instruction')"/>
</xs:complexType>
<xs:simpleType name="type2">
<xs:restriction base="xs:string">
<xs:enumeration value="Dice Roll"/>
<xs:enumeration value="Wait"/>
<xs:enumeration value="Repeat"/>
<xs:enumeration value="Double Roll"/>
<xs:enumeration value="Instruction"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="until">
<xs:restriction base="xs:string">
<xs:enumeration value="end"/>
<xs:enumeration value="random"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="annotation">
<xs:restriction base="xs:string">
<xs:enumeration value="rolltwice"/>
<xs:enumeration value="halfcount"/>
<xs:enumeration value="doublecount"/>
<xs:enumeration value="roll-"/>
<xs:enumeration value="roll+"/>
<xs:enumeration value="numberChange"/>
<xs:enumeration value="NoNumberChange"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="extended">
<xs:restriction base="xs:string">
<xs:enumeration value="noRolling"/>
<xs:enumeration value="noEven"/>
<xs:enumeration value="noUneven"/>
<xs:enumeration value="stopped"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
and that then makes the first instruction in below sample (also slightly adapted as there was a spelling difference between the schema and the sample (Dice roll vs. Dice Roll) in your snippets) valid while the second is invalid:
<root>
<instruction>
<type repeat='1' until='random'><random start='1' end='6'/>Dice Roll</type>
</instruction>
<instruction>
<type repeat='1' until='2'><random start='1' end='6'/>Dice Roll</type>
</instruction>
</root>

How to use condition in XSD [duplicate]

I need a required attribute or element only if a specific value of an enumeration is chosen. Example below:
<xs:element name="TYPE" type="TestEnum" />
<!-- // This Element should only required when TYPE = INTERNATIONAL -->
<xs:element name="IBAN"/>
</xs:complexType>
<xs:simpleType name="TestEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="NATIONAL"/>
<xs:enumeration value="INTERNATIONAL"/>
</xs:restriction>
</xs:simpleType>
XSD 1.1
Here's how use xs:assert to make IBAN be mandatory when TYPE = 'INTERNATIONAL':
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
vc:minVersion="1.1">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="TYPE" type="TestEnum" />
<!-- // This Element should only required when TYPE = INTERNATIONAL -->
<xs:element name="IBAN" minOccurs="0"/>
</xs:sequence>
<xs:assert test="not(TYPE = 'INTERNATIONAL') or IBAN"/>
</xs:complexType>
</xs:element>
<xs:simpleType name="TestEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="NATIONAL"/>
<xs:enumeration value="INTERNATIONAL"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

XSD: Different Restriction by Attribute Values

I'm new in XSD and have the following question, thanks a lot for your help!
Suppose I have the xml:
<DataGroup>
<Data name="name">Jane</Data>
<Data name="age">50</Data>
<Data name="state>MA</Data>
<Data name="zipcode">01000</Data>
</DataGroup>
I'd like to put restriction on:
when the attribute name equals to "age", the value of should be an integer and >20,
when the attribute name equals to "state", the value of should be two letters.
when the attribute name equals to "zip code", the value of should be \d{5}.
Can not modify the xml, any idea?
Thanks!
Using XSD 1.1 you can declare alternative types for each situation. Additionally you can restrict the number of <Data> elements to exactly four, and add an assertion to guarantee that each different attribute occurs exactly once:
<xs:element name="DataGroup">
<xs:complexType>
<xs:sequence>
<xs:element name="Data" maxOccurs="4" minOccurs="4">
<xs:alternative type="NameData" test="#name='name'" />
<xs:alternative type="AgeData" test="#name='age'" />
<xs:alternative type="ZipData" test="#name='zipcode'"/>
<xs:alternative type="StateData" test="#name='state'"/>
</xs:element>
</xs:sequence>
<xs:assert test="Data/#name='name' and Data/#name='age' and Data/#name='zipcode' and Data/#name='state'"></xs:assert>
</xs:complexType>
</xs:element>
Since <Data> is a simple type, you need to declare the attribute as an extension of each type:
<xs:complexType name="NameData">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="AgeData">
<xs:simpleContent>
<xs:extension base="AgeType">
<xs:attribute name="name" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="ZipData">
<xs:simpleContent>
<xs:extension base="ZipType">
<xs:attribute name="name" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="StateData">
<xs:simpleContent>
<xs:extension base="StateType">
<xs:attribute name="name" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
The restrictions you declare in the types which are base for the simple types:
<xs:simpleType name="AgeType">
<xs:restriction base="xs:integer">
<xs:minExclusive value="20"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="StateType">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z]{2}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ZipType">
<xs:restriction base="xs:string">
<xs:pattern value="\d{5}"/>
</xs:restriction>
</xs:simpleType>
This will validate your file with the restrictions you require.

XSD Restriction on Attribute

I think I have searched a lot about this but still no go.
Will appreciate any help.
I am trying to restrict an attribute for an element with empty content. "color" should have a restriction to only hold 3 digit or minLength=3 and maxLength=3. It should not have any content.
<?xml version="1.0" encoding="utf-8"?>
<items xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="">
<product id="" name="">
<article id="1001">
<umbrella color="100"/>
<umbrella color="101"/>
</article>
<article id="1002">
<umbrella color="110"/>
</article>
</product>
</items>
EDIT: I know how to do a XSD Restriction on a simpleType. But I don't how to combine it to one entity with a ComplexType.
If you could provide a more detailed (or full) solution I would be happy.
Btw, "color" is not limited to xs:integer. It is actually a xs:string.
You can define your attribute similar to the following. This example uses a pattern to restrict the value, but you could also use min and max if that's more appropriate.
<xs:attribute name="color">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:pattern value="[0-9][0-9][0-9]"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
Then in your element definition, you just use a ref to reference the defined attribute:
<xs:attribute ref="color"/>
UPDATE (in response to comment from OP):
Here's what the entire schema might look like:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:attribute name="color">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:pattern value="[0-9][0-9][0-9]"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="id">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:pattern value="[0-9][0-9][0-9][0-9]"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="name" type="xs:string"/>
<xs:complexType name="article_type">
<xs:attribute ref="color" use="required"/>
</xs:complexType>
<xs:element name="article">
<xs:complexType>
<xs:choice maxOccurs="unbounded" minOccurs="0">
<xs:element name="umbrella" type="article_type"/>
</xs:choice>
<xs:attribute ref="id" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="product">
<xs:complexType>
<xs:choice maxOccurs="unbounded" minOccurs="0">
<xs:element ref="article"/>
</xs:choice>
<xs:attribute ref="id" use="required"/>
<xs:attribute ref="name"/>
</xs:complexType>
</xs:element>
<xs:element name="items">
<xs:complexType>
<xs:choice maxOccurs="unbounded" minOccurs="0">
<xs:element ref="product"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
The following should work
<element name="umbrella" nillable="true" type="umbrellaType">
<complexType name="umbrellaType">
<attribute name="color">
<simpleType>
<restriction base="int">
<minExclusive value="99"></minExclusive>
<maxInclusive value="999"></maxInclusive>
</restriction>
</simpleType>
</attribute>
</complexType>

xsd element with the same name

to make xsd for element with same names that only identifyed by attribute value example :-
<a>
<b n="structure one">
<c n="inner element 1"/>
<c n="inner element 2"/>
<c n="inner element 3"/>
</b>
<b n="structure two">
<c n="inner element 1 for structure two"/>
<c n="inner element 2 for structure two"/>
<c n="inner element 3 for structure two"/>
</b>
</a>
notice that from the XML i have to mention specific value that belong to the inner element same for structure
Not sure what your specific requirements are, but the following schema validates your document. It says that the root element must be named a, and it can contain any number of b elements, which themselves contain any number of c elements. The b and c elements must contain the attribute with the name n.
<xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="a">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="b">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="c">
<xs:complexType>
<xs:attribute name="n" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="n" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
If you want to constrain the attributes to a specific set of values, you can use a restriction. This schema enumerates the possible values of the n attributes on the b and c elements:
<xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="a">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="b" type="b"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="b">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="c">
<xs:complexType>
<xs:attribute name="n" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="inner element 1"/>
<xs:enumeration value="inner element 2"/>
<xs:enumeration value="inner element 3"/>
<xs:enumeration value="inner element 1 for structure two"/>
<xs:enumeration value="inner element 2 for structure two"/>
<xs:enumeration value="inner element 3 for structure two"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="n" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="structure one"/>
<xs:enumeration value="structure two"/>
<xs:enumeration value="structure three"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:schema>
You can also constrain the values of the attributes with a regex pattern, like this:
<xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="a">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="b" type="b"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="b">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="c">
<xs:complexType>
<xs:attribute name="n" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="^inner element [0-9]+.*$"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="n" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="structure (one|two|three)"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:schema>

Resources