1

I'm new to XML and I was given two assignments recently involving XML and Schema. If I take out the schema the browser displays the XML but when I add the schema I get an error at the root element that says there is extra content at the end of the document. I looked through some answers on here and most of them have two root elements, or a space in the name of one of the element names, but that isn't issue.

I know it's something simple but I've been looking for a few hours and have really hit a wall with this.

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
<xsd:element name="table">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:element name="id" type="xsd:string"/>
            <xsd:element name="name" type="xsd:string"/>
            <xsd:element name="stars">
                <xsd:simpletype>
                    <xsd:restriction base="xsd:positiveinteger">
                        <xsd:mininclusive value="0"/>
                        <xsd:maxinclusive value="5"/> 
                    </xsd:restriction>
                </xsd:simpletype>
            </xsd:element>
            <xsd:element name="facilities">
                <xsd:simpletype>
                    <xsd:restriction base="xsd:string">
                        <xsd:enumeration value="Internet"/>
                        <xsd:enumeration value="Gym"/>
                        <xsd:enumeration value="Parking"/>
                        <xsd:enumeration value="Restaurant"/>
                        <xsd:enumeration value="Pick-up"/>
                    </xsd:restriction>
                </xsd:simpletype>
            </xsd:element>
            <xsd:element name="address" type="xsd:string"/>
            <xsd:element name="distancefromcenter" type="xsd:integer" minoccurs="0"/>
            <xsd:element name="available" type="xsd:boolean"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>
</xsd:schema>
<table>
    <hotel>
        <id>1</id>
        <name>Les Jardins du Marais</name>
        <stars>3</stars>
        <facilities>Internet</facilities>
        <address>74 rue Amelot, Paris, 75011</address>
        <distancefromcenter>2</distancefromcenter>
        <available>True</available>
    </hotel>

    <hotel> 
        <id>2</id>
        <name>Golden Tulip Little Palace</name>
        <stars>4</stars>
        <facilities>Internet Gym Parking Restaurant</facilities>
        <address>4 rue Salomon De Caus, Paris, 75003</address>
        <distancefromcenter>0.1</distancefromcenter>
        <available>False</available>
    </hotel>

    <hotel> 
        <id>3</id>
        <name>Tilsitt Etoile</name>
        <stars>2</stars>
        <facilities>Restaurant</facilities>
        <address>23 rue Brey, Paris, 75017</address>
        <distancefromcenter>3</distancefromcenter>
        <available>False</available>
    </hotel>

    <hotel> 
        <id>4</id>
        <name>Hotel Saint Charles</name>
        <stars> 3</stars>
        <facilities>Parking</facilities>
        <address>6 rue de I'Esperance, Paris, 75013</address>
        <distancefromcenter>1</distancefromcenter>
        <available>True</available>
    </hotel>
</table>
Bryan M.
  • 13
  • 2

2 Answers2

1

The XSD cannot be in the same file as the XML document1. If you're presenting both together as shown in your example, you have two root elements, and that's never allowed in XML.

Instead use schemaLocation or noNamespaceSchemaLocation to hint to the XML processor regarding the location of the XSD (in a separate file).

See How to link XML to XSD using schemaLocation or noNamespaceSchemaLocation?


1 Without unnatural contortions of little practical value to practitioners looking to validate their XML against their XSD. But see C. M. Sperberg-McQueen's interesting assessment of how in theory an XSD, like DTDs before it, might reside in the same XML document that it's meant to govern.

Community
  • 1
  • 1
kjhughes
  • 106,133
  • 27
  • 181
  • 240
1

In practice, you will normally want to have the XML instance document and its schema be in different XML documents; use the command-line options or invocation parameters provided by your validator to point at the schema. If your validator doesn't provide suitable command-line options and you cannot junk it and get a validator with a better-designed interface, then you will probably be able to use the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attributes mentioned by kjhughes.

But it's not quite true to say that the XSD 'schema document' (which the XSD spec defines to mean 'the xsd:schema element') and the XML to be validated cannot be in the same XML document. It is quite possible, in principle.

But if you want to do it that way, you will need to make a number of changes.

First, make a well-formed XML document. One simple way to do this is to wrap your existing material (one xsd:schema element and one table element) in a wrapper:

<wrapper>
  <xsd:schema targetNamespace="http://example.com/ns/BryanM."
              xmlns="http://example.com/ns/BryanM."
              elementFormDefault="qualified"
              id="myschema">
    ...
  </xsd:schema>
  <table xmlns="http://example.com/ns/BryanM.">
    ...
  </table>
</wrapper>

Another is to embed the xsd:schema element in the table somewhere.

<table xmlns="http://example.com/ns/BryanM.">
  <xsd:schema targetNamespace="http://example.com/ns/BryanM."
              xmlns="http://example.com/ns/BryanM."
              elementFormDefault="qualified"
              id="myschema">
    ...
  </xsd:schema>
  <hotel>
    ...
  </hotel>
  ...
</table>

I've provided xml:id attributes on the schema elements for reasons that will become clear in a moment.

I've also changed your target namespace from w3schools.com (which you should not be using for your schema, unless you are the owner of that domain) to a namespace with the host name example.com (which is reserved for examples); this has nothing to do with schema validity, only to do with proper use of namespaces.

Second, you will need to tell the validator where to find your schema. The validator you are using may provide command-line options or invocation parameters for that information, in which case you can use them to point to the xsd:schema element; otherwise, you may want to add the following to the wrapper or table elements:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://example.com/ns/BryanM. #myschema"

As you may be able to see, this xsi:schemaLocation attribute says, in effect "Hi, there, XSD validator! If you don't already have a schema for namespace http://example.com/ns/BryanM., you can find one at the URI #myschema, that is, at the element with ID myschema in this very document." This is why the xsd:schema element needs to carry an ID.

Third, you will need either to tell the validator which element you want to validate against the schema, or (probably more likely) ensure that it can validate the root element of the document (wrapper in the first example, table in the second). Very few XSD validators with a command-line interface actually provide an option for identifying what XML element(s) you want them to validate; they just silently assume that they are being asked to validate the entire document. Validator functions to be called via an API are I think more likely to provide that capability.

If your validator insists on validating the entire XML document (some do), then you'll need to ensure that your schema is up to the job; the simplest way, if you're using a 'wrapper' element, is to add something like

<xsd:element name="wrapper"/>

to the schema. (Depending on how the validator handles some implementation-defined behavior in XSD 1.0, this may or may not be strictly necessary.) If you're using the second approach (embedding the schema in the table element), you'll need to modify the 'table' element so that it is allowed to contain a child named 'xsd:schema'; I won't go into details here.

Unfortunately, while all this is possible in principle, the fact is that there is very little interoperability among validators which allow the schema to be embedded in the input XML document; the spec gives them no guidance, and proposals that the XSD WG should write a Note describing recommended practices failed due to lack of consensus in the WG on the utility of such a Note (or even on the utility of making a survey of existing practice). So while I think it's not quite right to say, as kjhughes does, that the schema cannot be in the same XML document as the input to be validated, it's almost always going to be better that way in practice.

C. M. Sperberg-McQueen
  • 24,596
  • 5
  • 38
  • 65
  • This is interesting and ought not be buried under a question to which it's only tangentially related. Consider adding a question and self-answer under a title such as "Can an XSD be embedded in XML like a DTD?" – kjhughes Feb 28 '16 at 03:08