问题
Im am trying to create an XML schema for the following XML document. https://www.nationalbanken.dk/_vti_bin/DN/DataService.svc/CurrencyRatesHistoryXML?lang=en
Then I have installed installed the XML tools plugin to my Notepad++ and tried to validate the XML doc agains the schema.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.ecb.int/vocabulary/2002-08-01/eurofxref" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref" elementFormDefault="qualified">
<xs:element name="Envelope">
<xs:complexType>
<xs:sequence>
<xs:element name="subject" type="xs:string"></xs:element>
<xs:element name="Sender">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Cube">
<xs:complexType>
<xs:sequence>
<xs:element name="Cube" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Cube" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="currency" type="xs:string"></xs:attribute>
<xs:attribute name="rate" type="xs:double"></xs:attribute>
<xs:attribute name="name" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="time" type="xs:date"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XML to be validated
<gesmes:Envelope
xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01"
gesmes:schemaLocation="http://www.ecb.int/vocabulary/2002-08-01/eurofxref ..\StockDownloadResources\CurrenciesDownloadMANUAL.XSD">
<gesmes:subject>Exhange rates</gesmes:subject>
<gesmes:Sender>
<gesmes:name>Danmarks Nationalbank</gesmes:name>
</gesmes:Sender>
<Cube>
<Cube time="2019-07-25">
<Cube currency="AUD" rate="468.22" name="Australian dollars"/>
<Cube currency="BGN" rate="381.68" name="Bulgarian lev"/>
<Cube currency="BRL" rate="178.71" name="Brazilian real"/>
<Cube currency="CAD" rate="511.60" name="Canadian dollars"/>
<Cube currency="CHF" rate="679.30" name="Swiss francs"/>
<Cube currency="CNY" rate="97.72" name="Chinese yuan renminbi"/>
<Cube currency="CZK" rate="29.25" name="Czech koruny"/>
<Cube currency="EUR" rate="746.48" name="Euro"/>
<Cube currency="GBP" rate="839.09" name="Pounds sterling"/>
<Cube currency="HKD" rate="85.95" name="Hong Kong dollars"/>
<Cube currency="HRK" rate="101.10" name="Croatian kuna"/>
<Cube currency="HUF" rate="2.295" name="Hungarian forints"/>
<Cube currency="IDR" rate="0.0480" name="Indonesian rupiah"/>
<Cube currency="ILS" rate="190.49" name="Israeli shekel"/>
<Cube currency="INR" rate="9.74" name="Indian rupee"/>
<Cube currency="ISK" rate="5.493" name="Icelandic kronur *"/>
<Cube currency="JPY" rate="6.2129" name="Japanese yen"/>
<Cube currency="KRW" rate="0.5689" name="South Korean won"/>
<Cube currency="MXN" rate="35.35" name="Mexican peso"/>
<Cube currency="MYR" rate="163.23" name="Malaysian ringgit"/>
<Cube currency="NOK" rate="77.71" name="Norwegian kroner"/>
<Cube currency="NZD" rate="449.80" name="New Zealand dollars"/>
<Cube currency="PHP" rate="13.14" name="Philippine peso"/>
<Cube currency="PLN" rate="175.76" name="Polish zlotys"/>
<Cube currency="RON" rate="158.06" name="Romanian leu"/>
<Cube currency="RUB" rate="10.65" name="Russian rouble"/>
<Cube currency="SEK" rate="71.13" name="Swedish kronor"/>
<Cube currency="SGD" rate="491.78" name="Singapore dollars"/>
<Cube currency="THB" rate="21.76" name="Thai baht"/>
<Cube currency="TRY" rate="118.47" name="Turkish lira"/>
<Cube currency="USD" rate="671.60" name="US dollars"/>
<Cube currency="XDR" rate="925.37" name="SDR (Calculated **)"/>
<Cube currency="ZAR" rate="48.26" name="South African rand"/>
</Cube>
<!-- MORE CUBES HAS BEEN DELETED -->
</Cube>
</gesmes:Envelope>
But when I try to validate the schema I recieve the following validation error:
Validation of current file using XML schema: ERROR: Element '{http://www.gesmes.org/xml/2002-08-01}Envelope': No matching global declaration available for the validation root.
When googling this validation error and when submitting this question you will find a range of people that have had the same type of error. But none of the ones I have come across have guided me enough to solve the issue.
What am I missing ?
回答1:
Lets look at the XML first. It defines the following namespaces and prefixes:
xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01"
The xmlns=
says that XML elements with no prefix (i.e. Cube) are in the http://www.ecb.int/vocabulary/2002-08-01/eurofxref
namespace. The xmlns:gesmes
says that XML elements with the gesmes
prefix (i.e. Envelope, subject, Sender, name) are in the http://www.gesmes.org/xml/2002-08-01
namespace.
However, your schema defines the targetNamespace to be http://www.ecb.int/vocabulary/2002-08-01/eurofxref
, which means validation expects the Envelope element to be in that namespace. But the xml says it should be in the other namespace. This results in an error about not being able to find the expected element in the expected namespace.
The first thing to realize is that a schema file can only define elements in a single namespace, as set by the targetNamespace attribute. But the XML mixes elements with different namespaces. So we immediately know we must have two schema files with different namespaces, and one must import the other. So one schema for the envelope stuff, and one schema for the cube stuff.
Let's start with the Cube schema since it's the inner element. Cube elements are in the http://www.ecb.int/vocabulary/2002-08-01/eurofxref
namespace, so that should be the targetNamespace of that schema. Then we define just the Cube element like you have, something like this:
cube.xsd
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
elementFormDefault="qualified">
<xs:element name="Cube">
<!-- The rest of your Cube element definition -->
</xs:element>
</xs:schema>
So all the Cube elements now have a schema that puts them in the right namespace.
Now we need to define the envelope schema, referencing that Cube element we just defined. The Envelope elements are in the http://www.gesmes.org/xml/2002-08-01
namespace, so that will be our targetNamespace. And it would be good to define a namespace prefix so we can reference the cube namespace. And we need to import the cube schema so we can reference that Cube element in that namespace. Something like this:
envelope.xsd
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:cube="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
targetNamespace="http://www.gesmes.org/xml/2002-08-01"
elementFormDefault="qualified">
<xs:import schemaLocation="cube.xsd" namespace="http://www.ecb.int/vocabulary/2002-08-01/eurofxref" />
<xs:element name="Envelope>
<xs:complexType>
<xs:sequence>
...
<xs:element ref="cube:Cube" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
So this defines the Envelope, subject, Sender, and name elements to be in the correct gesmes namespace, and references the Cube element in the Cube namespace.
回答2:
The comments field does not allow enought letters to give a thorough update.
First thanks to stevedlawrence who already gave us some insight :)
cube.xsd
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
elementFormDefault="qualified">
<xs:element name="Cube">
<!-- The rest of your Cube element definition -->
<xs:complexType>
<xs:sequence>
<xs:element name="Cube" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Cube" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="currency" type="xs:string"></xs:attribute>
<xs:attribute name="rate" type="xs:double"></xs:attribute>
<xs:attribute name="name" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="time" type="xs:date"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
envelope.xsd
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:cube="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
targetNamespace="http://www.gesmes.org/xml/2002-08-01"
elementFormDefault="qualified">
<xs:import schemaLocation="cube.xsd" namespace="http://www.ecb.int/vocabulary/2002-08-01/eurofxref" />
<xs:element name="Envelope">
<xs:complexType>
<xs:sequence>
<xs:element name="subject" type="xs:string"></xs:element>
<xs:element name="Sender">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element ref="cube:Cube" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
The XML file downloaded
<gesmes:Envelope
xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01"
gesmes:schemaLocation="http://www.ecb.int/vocabulary/2002-08-01/eurofxref ..\StockDownloadResources\envelope.xsd">
<gesmes:subject>Exhange rates</gesmes:subject>
<gesmes:Sender>
<gesmes:name>Danmarks Nationalbank</gesmes:name>
</gesmes:Sender>
<Cube>
<Cube time="2019-07-25">
<Cube currency="AUD" rate="468.22" name="Australian dollars"/>
<Cube currency="BGN" rate="381.68" name="Bulgarian lev"/>
<Cube currency="BRL" rate="178.71" name="Brazilian real"/>
<Cube currency="CAD" rate="511.60" name="Canadian dollars"/>
<Cube currency="CHF" rate="679.30" name="Swiss francs"/>
<Cube currency="CNY" rate="97.72" name="Chinese yuan renminbi"/>
<Cube currency="CZK" rate="29.25" name="Czech koruny"/>
<Cube currency="EUR" rate="746.48" name="Euro"/>
<Cube currency="GBP" rate="839.09" name="Pounds sterling"/>
<Cube currency="HKD" rate="85.95" name="Hong Kong dollars"/>
<Cube currency="HRK" rate="101.10" name="Croatian kuna"/>
<Cube currency="HUF" rate="2.295" name="Hungarian forints"/>
<Cube currency="IDR" rate="0.0480" name="Indonesian rupiah"/>
<Cube currency="ILS" rate="190.49" name="Israeli shekel"/>
<Cube currency="INR" rate="9.74" name="Indian rupee"/>
<Cube currency="ISK" rate="5.493" name="Icelandic kronur *"/>
<Cube currency="JPY" rate="6.2129" name="Japanese yen"/>
<Cube currency="KRW" rate="0.5689" name="South Korean won"/>
<Cube currency="MXN" rate="35.35" name="Mexican peso"/>
<Cube currency="MYR" rate="163.23" name="Malaysian ringgit"/>
<Cube currency="NOK" rate="77.71" name="Norwegian kroner"/>
<Cube currency="NZD" rate="449.80" name="New Zealand dollars"/>
<Cube currency="PHP" rate="13.14" name="Philippine peso"/>
<Cube currency="PLN" rate="175.76" name="Polish zlotys"/>
<Cube currency="RON" rate="158.06" name="Romanian leu"/>
<Cube currency="RUB" rate="10.65" name="Russian rouble"/>
<Cube currency="SEK" rate="71.13" name="Swedish kronor"/>
<Cube currency="SGD" rate="491.78" name="Singapore dollars"/>
<Cube currency="THB" rate="21.76" name="Thai baht"/>
<Cube currency="TRY" rate="118.47" name="Turkish lira"/>
<Cube currency="USD" rate="671.60" name="US dollars"/>
<Cube currency="XDR" rate="925.37" name="SDR (Calculated **)"/>
<Cube currency="ZAR" rate="48.26" name="South African rand"/>
</Cube>
<!-- MORE CUBES HAS BEEN DELETED -->
</Cube>
</gesmes:Envelope>
When I run the Notepad++ verification of the schema now i get this error:
Validation of current file using XML schema: ERROR: Element '{http://www.gesmes.org/xml/2002-08-01}Envelope', attribute '{http://www.gesmes.org/xml/2002-08-01}schemaLocation': The attribute '{http://www.gesmes.org/xml/2002-08-01}schemaLocation' is not allowed.
来源:https://stackoverflow.com/questions/57411742/xml-schema-no-matching-global-declaration-available-for-the-validation-root