0
votes

I have an XML file and two XSD files. Both XSD files are well-formed and validate. The XML file is well formed, but when I try to validate it, it says "Error at line 25, clumn 46: type 'http://www.w3.org/2001/XMLSchema:topicType' not found. Is that an error with the import statement? Is something wrong with my code for the imported XSD file where I declare topicType? Something wrong with the XML file? Any help will be greatly appreciated as I can't seem to fix the error.

XML File:

<?xml version="1.0" encoding="UTF-8"?>
<presentations
  xmlns="http://www.example.com/contacts"
xmlns:name="http://www.example.com/name"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com/contacts main.xsd"
  source="Beginning XML 5E"
  version="1.0">

  <presentation date="2013-07-31" length="PT30M">
    <topic genre="Music">PianoML</topic>
    <presenters>
      <name title="Mr." id="Y258">
        <first>Elvis</first>
        <middle>A</middle>
        <last>Presley </last>
      </name>
      <name title="Miss" id="X365">
        <first>Lady</first>
        <last>Gaga</last>
      </name>
    </presenters>
  </presentation>

    <presentation date="2013-08-05" length="PT35M">
    <topic genre="Science">AlienML</topic>
    <presenters>
         <name title="Mr." id="Y007">
        <first>Will</first>
        <last>Smith</last>
      </name>
      <name title="Mr." id="Y360">
        <first>Tommy</first>
        <first>Lee</first>
        <last>Jones</last>
      </name>
    </presenters>
  </presentation>
</presentations>

Main XSD File:

<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
  xmlns:contacts="http://www.example.com/contacts"
  xmlns:name="http://www.example.com/name"
  targetNamespace="http://www.example.com/contacts"
  elementFormDefault="qualified">

 <import namespace="http://www.example.com/name" schemaLocation="topic.xsd" />

   <!-- Presentations Element -->
    <complexType name="presentationsType">
      <sequence minOccurs="0" maxOccurs="unbounded">
        <element ref="presentation"/>
      </sequence>
    </complexType>

  <!-- Presentation Element -->
    <complexType name="presentationType">
      <sequence>
        <element ref="topic"/>
        <element ref="presenters"/>
      </sequence>
      <!-- Attribute group reference for presentation Element -->
      <attributeGroup ref="presentationAttr" />
    </complexType>

<!-- Presenters Element -->
    <complexType name="presentersType">
      <sequence minOccurs="1" maxOccurs="unbounded">
        <element ref="name"/>
      </sequence>
    </complexType>

<!-- Name Element -->
    <complexType name="nameType">
      <!-- Element group reference for name Group -->
      <group ref="nameGroup" />
      <!-- Attribute group reference for name Element -->
      <attributeGroup ref="nameAttr" />
    </complexType>


<!-- Element declarations -->
  <element name="presentations" type="presentationsType" />
  <element name="presentation" type="presentationType" />
  <element name="presenters" type="presentersType" />
  <element name="name" type="nameType" />
  <element name="first" type="string"/>
  <element name="middle" type="string"/>
  <element name="last" type="string"/>

  <!--Element group definition for name Element -->
  <group name="nameGroup">
      <sequence>
        <sequence minOccurs="1" maxOccurs="unbounded">
          <element ref="first"/>
        </sequence>
        <sequence minOccurs="0" maxOccurs="1">
          <element ref="middle"/>
        </sequence>
        <element ref="last"/>
      </sequence>
  </group>

  <!-- Attribute group definition for presentation Element -->
  <attributeGroup name="presentationAttr">
      <attribute name="date" type="date" use="required"/>
      <attribute name="length" type="duration" use="required"/>
  </attributeGroup>

  <!-- Attribute group definition for name Element -->
  <attributeGroup name="nameAttr">
      <!-- ID must begin with either X or Y and be followed by 3 digits -->
      <attribute name="id" use="required">
          <simpleType>
               <restriction base="ID">
                   <pattern value="[X|Y][0-9]{3}" />
              </restriction>
         </simpleType>
     </attribute>
      <!-- Title attribute must be either Mr., Mrs., Ms., or Miss -->
      <attribute name="title" use="required">
        <simpleType>
          <restriction base="string">
            <enumeration value="Mr."/>
            <enumeration value="Mrs."/>
            <enumeration value="Ms."/>
            <enumeration value="Miss"/>
          </restriction>
        </simpleType>
      </attribute>
  </attributeGroup>

</schema>

Imported XSD File:

<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
  xmlns:target="http://www.example.com/name"
  targetNamespace="http://www.example.com/name"
  elementFormDefault="qualified">

<!-- Topic Element -->
    <complexType name="topicType">
      <simpleContent>
        <extension base="string">
          <attribute name="genre" use="required">
            <simpleType>
              <restriction base="string">
                <enumeration value="ART" />
                <enumeration value="Music" />
                <enumeration value="Science" />
                <enumeration value="Technology" />
              </restriction>
            </simpleType>
          </attribute>
        </extension>
      </simpleContent>
    </complexType>

    <element name="topic" type="topicType" /> 
</schema>
1

1 Answers

1
votes

Firstly, you have a problem regarding the usage of the default namespace and the target namespacein the main schema. The default namespace is the XML schema namespace which means that all unqualified elements and type references refer to that namespace.

However, the types you define in the schema belong to the target namespace, and when you refer to them, they must be qualified, since the target namespace is not the default namespace. For convenience, you should normally have the default namespace the same as the target namespace. But, in this case, let's stick to the namespace declarations that you have, and it means that you must qualify your type references. An example:

<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:contacts="http://www.example.com/contacts"
    xmlns:name="http://www.example.com/name" targetNamespace="http://www.example.com/contacts"
    elementFormDefault="qualified">

    <import namespace="http://www.example.com/name" schemaLocation="topic.xsd" />

    <!-- Presentations Element -->
    <complexType name="presentationsType">
        <sequence minOccurs="0" maxOccurs="unbounded">
            <element ref="contacts:presentation" />
        </sequence>
    </complexType>
</schema>

Note the use of contacts:presentation instead of just presentation.

Secondly, the main.xsd schema doesn't correctly refer to the type in the topic.xsd. You must again qualify the type reference with the namespace prefix:

<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:contacts="http://www.example.com/contacts"
    xmlns:name="http://www.example.com/name" targetNamespace="http://www.example.com/contacts"
    elementFormDefault="qualified">

    ...

    <!-- Presentation Element -->
    <complexType name="presentationType">
        <sequence>
            <element ref="name:topic" />
            <element ref="contacts:presenters" />
        </sequence>
        <!-- Attribute group reference for presentation Element -->
        <attributeGroup ref="contacts:presentationAttr" />
    </complexType>

   ...

</schema>

Note the use of name:topic instead of just topic.

Thirdly, you must qualify the usage of the topic element in your XML instance document, since that element is defined to live in the name namespace:

<?xml version="1.0" encoding="UTF-8"?>
<presentations 
    xmlns="http://www.example.com/contacts"
    xmlns:name="http://www.example.com/name"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.example.com/contacts main.xsd" >

    <presentation date="2013-07-31" length="PT30M">
        <name:topic genre="Music">PianoML</name:topic>
        <presenters>
            <name title="Mr." id="Y258">
                <first>Elvis</first>
                <middle>A</middle>
                <last>Presley </last>
            </name>
            <name title="Miss" id="X365">
                <first>Lady</first>
                <last>Gaga</last>
            </name>
        </presenters>
    </presentation>
</presentations>

Well, that's about it, I guess ;)

Update What would it look like to use the "recommended" style of namespace prefixes?

NB. This is not a an officially recommended usage--just a common practice that makes it easier to to refer to local type definitions.

Take the second schema as an example: the target namespace is the same as the default namespace:

<?xml version="1.0"?>
<xsd:schema 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="http://www.example.com/name" 
    targetNamespace="http://www.example.com/name"
    elementFormDefault="qualified">

    <!-- Topic Element -->
    <xsd:complexType name="topicType">
        <xsd:simpleContent>
            <xsd:extension base="xsd:string">
                <xsd:attribute name="genre" use="required">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                            <xsd:enumeration value="ART" />
                            <xsd:enumeration value="Music" />
                            <xsd:enumeration value="Science" />
                            <xsd:enumeration value="Technology" />
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:attribute>
            </xsd:extension>
        </xsd:simpleContent>
    </xsd:complexType>

    <xsd:element name="topic" type="topicType" />
</xsd:schema>

Now, in the element topic declaration, you can refer to the topicType without qualifying it (something I missed to point out in the original anser, btw). But note as well, that you now have to qualify the references to the built-in schema schema types e.g xsd:string.