Ms.Smith
Ms.Smith

Reputation: 483

How to include 2 xsd schemas into 1 xml file?

my question is about 2 XSD schemas that must be the base for an XML document. For me it was easier to create first the XML I need and then to create those XSD schemas. So, I've got three files here.

1st XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema  xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.w3schools.com">

    <xs:element name="studentAI">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="gender">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:enumeration value="female"/>
                            <xs:enumeration value="male"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
                <xs:element name="age">
                    <xs:simpleType>
                        <xs:restriction base="xs:integer">
                            <xs:minInclusive value="0"/>
                            <xs:maxInclusive value="100"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
                <xs:element name="other" type="desc"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="desc">
        <xs:sequence>
            <xs:element name="height" type="xs:string"/>
            <xs:element name="weight" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>

</xs:schema>

2nd XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema  xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.w3schools.com">

    <xs:element name="group">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="student" minOccurs="2" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="student">
        <xs:sequence>
             <xs:element name="surname" type="xs:string"/>
           <xs:element name="name" type="xs:string"/>
            <xs:element name="birthday">
                <xs:simpleType>
                    <xs:restriction base="xs:date"/>
                </xs:simpleType>
            </xs:element>
            <xs:element name="parents" type="parentsDetails"/>
            <xs:element name="allCourses" type="allCoursesDetails"/>
        </xs:sequence>
        <xs:attribute name="id" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="parentsDetails">
        <xs:sequence>
           <xs:element name="father" type="xs:string"/>
           <xs:element name="mother" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>

   <xs:complexType name="allCoursesDetails">
        <xs:sequence>
            <xs:element name="course" type="courseDetails" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
   </xs:complexType>

    <xs:complexType name="courseDetails">
        <xs:attribute name="nr" use="required"/>
    </xs:complexType>

</xs:schema>

And the XML document I need to get on the base of those 2 XSD schemas (sorry, it's empty now but of course there must be info and it will be more than one student in the group):

<group xmlns:xs="http://www.w3schools.com"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://www.w3schools.com ">

    <student id="1">
        <surname></surname>
        <name></name>
        <birthday></birthday>
        <parents>
            <father></father>
            <mother></mother>
        </parents>
        <allCourses>
            <course nr="01"></course>
            <course nr="02"></course>
        </allCourses>
        <studentAI>
            <gender></gender>
            <age></age>
            <other>
                <height></height>
                <weight></weight>
            </other>
        </studentAI>
    </student>
</group>

I really don't know how to include those 2 XSD schemas in my XML document. Should I include both of them into the XML doc or I should first to include the 1st XSD schema into the 2nd one (as it is so on the result XML) and then to include the united one into the XML doc? And how to do that?

My biggest question is about upper part of all three documents where one should put declaration of namespaces and so on.

As for the program I'm trying to use it is Oxygen (I have 30 days lisense).

I really hope that someone will help me with this. I also hope that my question is clear.

Many many thanks in advance for the help!

Upvotes: 3

Views: 5327

Answers (2)

Michael Kay
Michael Kay

Reputation: 163625

First, your terminology is adrift. A schema is a set of schema components. If you have two schemas, that means you really have one schema, which is the union of the schema components from both. The things you are talking about are not schemas, but schema documents, which are files containing XML representations of schema components.

Your two schema documents share the same target namespace. The namespace you have used http://www.w3schools.com, is a poor choice because it's a domain name that you don't own. But that's a matter of bad etiquette rather than a technical problem.

However, it's odd to see xsi:schemaLocation="http://www.w3schools.com ". If you must use xsi:schemaLocation to refer from an instance document to the schema, then the attribute should contain an even number of URIs: it's essentially a mapping from namespace URIs to the URL location of a schema document with that target namespace.

If the schema for a particular namespace is split across several schema documents, then xsi:schemaLocation can't refer to them all. It's best to have one schema document that describes the namespace in its entirety, either within a single document, or by pulling together all the constituent schema documents using xs:include declarations.

Personally, I find the idea of referring to schema documents from an instance rather unsatisfactory. You only need to validate an instance document if you don't trust it. But if you don't trust it, then you want to validate against a schema that YOU choose, not one that the instance document itself chooses. It doesn't make much sense to say "I want to check that this document is valid, but I don't care what schema it is valid against, I'll let the document itself decide that.".

Upvotes: 2

sergioFC
sergioFC

Reputation: 6016

You can merge the content of the two schemas in a unique schema on make a schema include another. Anyway you should correct this issues:

  1. If you use name or ref to reference a element in a namespace you need to qualify that reference (or simply use your targetNamespace as the default namespace in your xsds that is easier). So, bound your targetNamespace to a prefix.

    xmlns:w3="http://www.w3schools.com"
    

    Then correct your references, for example:

    <xs:element name="allCourses" type="w3:allCoursesDetails"/>
    

    OR simply set the targetNamespace as the default namespace in your xsds:

    xmlns="http://www.w3schools.com"
    

    this way unqualified references point to the default namespace, that is set to the target namespace.

  2. Then you should use elementFormDefault="qualified" in your/yours xs:schema if you want your XML to be valid with all the elements belonging to the targetNampesce. Otherwise some of your XML elements should belong to the target namespace and some of them shouldn't belong to any namespace.

  3. Add the contents of the first schema to the schema containing the student element OR add an include clause that makes the student schema include the studentAI:

    <xs:include schemaLocation="studentAI.xsd"/>
    
  4. After that you only need to validate the XML against the schema containing the student element, so you need to add xsi:schemaLocation in your XML:

    xsi:schemaLocation="http://www.w3schools.com xsd1.xsd"
    
  5. Remember that you can reference elements using ref . You need to add studentAI after allCourses element in the sequence:

    <xs:element name="allCourses" type="allCoursesDetails"/>
    <xs:element ref="studentAI"/>
    
  6. In addition remember that you can simplify the birthday element, you don't need the restriction element if you are not adding any restriction.

Hope this helps you.

EDIT: added some more things (items 5 and 6).

Upvotes: 2

Related Questions