Reputation: 31171
Validate an XML document using a schema.
The simplest form of the problem is shown in two files.
<?xml version="1.0"?>
<recipe xmlns:r="http://www.namespace.org/recipe">
<r:description>
<r:title>sugar cookies</r:title>
</r:description>
</recipe>
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
version="1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:r="http://www.namespace.org/recipe">
<xsd:complexType name="recipe">
<xsd:choice>
<xsd:element name="description" type="descriptionType"
minOccurs="1" maxOccurs="1" />
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="descriptionType">
<xsd:all>
<xsd:element name="title">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:minLength value="5" />
<xsd:maxLength value="55" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:all>
</xsd:complexType>
</xsd:schema>
The full error message from xmllint:
$ xmllint --noout --schema schema.xsd file.xml
file.xml:2: element recipe: Schemas validity error : Element 'recipe': No matching global declaration available for the validation root. file.xml fails to validate
What is the correct syntax (or what schema attributes are missing) to ensure that the given schema can be used to successfully validate the given XML document?
Upvotes: 62
Views: 117741
Reputation: 80186
recipe
globalOnly global element definitions can be used as root elements. Your schema only has complex types and hence the error.
Change the <xsd:complexType name="recipe">
to
<xsd:element name="recipe"><xsd:complexType>
:
Schema file: recipe-now-global.xsd
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
version="1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:r="http://www.namespace.org/recipe">
<xsd:element name="recipe">
<xsd:complexType>
<xsd:choice>
<xsd:element name="description" type="descriptionType"
minOccurs="1" maxOccurs="1" />
</xsd:choice>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="descriptionType">
<xsd:all>
<xsd:element name="title">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:minLength value="5" />
<xsd:maxLength value="55" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:all>
</xsd:complexType>
</xsd:schema>
Read more about this here
NOTE: This still won't validate, because you have an unreleated namespace error...
$ cat file.xml | xmllint --noout --schema recipe-now-global.xsd -
-:3: element description: Schemas validity error : Element '{http://www.namespace.org/recipe}description': This element is not expected. Expected is ( description ).
- fails to validate
...but it WILL validate if you ignore that namespace error quick-and-dirty like:
$ cat file.xml | sed 's/r://g' | xmllint --noout --schema recipe-now-global.xsd -
- validates
See tom redfern's answer for details on that namespace problem.
Upvotes: 21
Reputation: 31760
You need to change your XML instance. Your current one says that there is a type called description
in the namespace http://www.namespace.org/recipe
. However, in your XSD definition, the only types exposed in that namespace are called recipe
and descriptionType
.
So either define a type called description
in the XSD schema, or change your instance so you are referencing the recipe
type correctly:
File ns-changed.xml
:
<?xml version="1.0"?>
<r:recipe xmlns:r="http://www.namespace.org/recipe">
<description>
<title>sugar cookies</title>
</description>
</r:recipe>
UPDATE This is only half the solution - the other half is in @Aravind's answer here: https://stackoverflow.com/a/8426185/569662
Upvotes: 32
Reputation: 13673
In my practice, I got the No matching global declaration available for the validation root
in two cases:
If XSD does not contain an <xsd:element name="recipe" .../>
explained in @aravind-r-yarram's answer.
If <recipe/>
in XML does not contain an xmlns
attribute. In such case adding the xmlns
will help:
<recipe xmlns="http://www.namespace.org/recipe">
...
</recipe>
Upvotes: 12