Link to home
Start Free TrialLog in
Avatar of NGInterface
NGInterface

asked on

Importing XML namespace

Can anyone help me with this problem:

In my XSD schema document, I have the following line:

<xs:import namespace="http://starlight_namespace" schemaLocation="http://starlight_namespace.com/starlight.xsd">
(the namespaces are fictional for demonstrative purposes)

and then in my XSD body, I have defined an element in terms of an existing element from the starlight.xsd document:

<xs:element name="LargeElement">
   <xs:complexType>
      <xs:sequence>
         <xs:element ref="SL:starlight_one">
         ...

However, my browser says the XSD is invalid, saying that "SL:starlight_one" can't be found -- am I missing anything? I've perused online tutorials on this and cannot find anything different...

Any help will be appreciated (with points!)
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

Hi NGInterface,

There are some things you need to take into account

in the above example the value of namespace="http://starlight_namespace" is a URI,
an identifier for the namespace. You have to make sure that this value is the same as the identifier you gave to the schema you import.
In other words, the imported schema needs to have a TargetNamespace with the same value

In the above example the value of schemaLocation="http://starlight_namespace.com/starlight.xsd" is a URL
that means it is a real reference to a resource. In other words, you have to make sure that the schema is found on that exact web address.

What I don't see in your snippet is a binding between the prefix and the namespace
so you should have in the root of your XML: xmlns:SL="http://starlight_namespace"

Then you should be fine

Cheers!
Avatar of NGInterface
NGInterface

ASKER

Thanks Gertone! Everything you mentioned checked out. I have just one more question related to this import of namespaces -- if I have another XSL sheet that takes an external (completely unrelated) document and transforms it to the document that is an instance of the XSD schema that I mentioned above, I DON'T have to import the starlight schema in the XSL right (and just have to define the xmlns:SL=... in the XSL...)? (Just wanted to make sure I didn't miss anything as this whole namespace thing is very confusing despite reading them up on the web...)
You don't have to import the schema in the XSLT.
usually you would import schemas in a schema
and import stylesheets in a stylesheet

If you want to indicate that the result of your transform has to be valid according to the starlight schema,
you can set the following in the root or the stylesheet element

<SL:starlight
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://starlight_namespace http://starlight_namespace.com/starlight.xsd"
     xmlns:SL="http://starlight_namespace">

this way your resulting XML has a correct reference to its schema

cheers

Geert
Hmm, I have two new problems with this:

- When I import ANOTHER externally defined xsd (say, "webstar.xsd") using another <xs:import...> command, it seems to be ignored (the second schema's elements, when referenced, makes the validator complain:

<xs:element ref="webstar:web_star_element"/>

- When I try to create an arbitrary namespace such as:

xmlns:new_ns="<insert uri here>"

and then try to define an element in this namespace:

<xs:element name="new_ns:new_element">
... (more stuff here)...

the validator complains.

Can you please tell me what's going on? Thanks!
you can import as many schema files as you want.
Note that you use import only if the namespaces of the importing schema and the imported schema are NOT equal
otherwise you should use "include"

then doublecheck the following (as before)
- is the value of the namespace attribute equal to the targetNamespace attribute of the imported schema
- is the value of schemaLocation attribute equal to the correct fysical address of the imported schema (address and filename)
- if the above is not a web address but a file on disk, is your path reference correct
- do you have a xmlns attribute that is in scope, that links the prefix to the correct namespace
- did you validate the imported schema and is it valid

import does not require a valid schema at the other end, because it mainly serves the definition of a namespace
so if your parser finds an invalid schema to import, it might just not throw an error

as to your second question
make sure that the schema you are making is valid
and has a targetnamespace you can use to reference it

can you tell me what complaint the validator has?

cheers

Geert
Okay, thanks! I resolved the first question. The second question still remain: it seems that the validator is actually having problems with the Schema (.xsd file) itself:

" Invalid 'name' attribute value 'new_ns:new_element': 'The ':' character, hexadecimal value 0x3A, at position 4 within the name, cannot be included in a name.'."

But I have already defined the namespace pointed to by new_ns, namely:

<xs:schema
            targetNamespace="<target_namespace>"
            ...(more namespaces here)...
            xmlns:new_ns="http://some_namespace_here" <!-- this is a made up namespace, it doesn't have a schema -->
            elementFormDefault="qualified">

So why is this

<xs:element name="new_ns:new_element">
... (more stuff here)...

raising complaints from the validator?
each element you define in the schema is automatically in the target namespace,
so you don't have to prefix it

<xs:element name="new_element">
is sufficient

you can then later reference it like this "new_ns:new_element"

sorry, I should have picked that up earlier
Hmm, what if the new_ns is not the target namespace? we wanted to "separate" our default namespace, which is "sunlight" (sorry, have to codename everything here...company policies), and want to include some more "conceptual" elements from another company, so we want to define a separate namespace for them (which for our purposes, is "new_ns"). That is, the other company did not define any XSD schema so we don't import anything, but we just want to conceptually say, "these elements are CONCEPTUALLY invented by that company", so ideally, we'd have something like:

<MyCompanyElement>
   <MyCompanySubElement>
      <new_ns:other_company_conceptual_element>
      ...
      ...

where MyCompanyElement and MyCompanySubElement are elements from our company, and new_ns:other_company_conceptual_element is from the other company (but remember, they did not define any schemas...)

so what u have said still holds? (that is, i just leave out the prefix for new_ns even if it is not the targetnamespace of my schema?)
aah, I begin to understand what you are doing
W
hat you have to do is the following

- you import that conceptual namespace in your schema, without actually loading a schema
- then you have the namespace available, but not the elements!
- in your schema you use the elements from the imported conceptual namespace with the prefix
- since you don't have an element definition, you have to use an xs:any, from that namespace, with validation lax or none

I will show you an example in a minute
Please note that the following example does not validate the conceptual elements
if you want that to happen, you need to build a schema for them in a seperate file
In XML schema, each namespace needs to be contained in a seperate file

here is a schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="urn:sunlight"
        xmlns="urn:sunlight"
        xmlns:new_ns="http://some_namespace_here">
    <xs:import namespace="http://some_namespace_here"/>
    <xs:element name="MyCompanyElement">
        <xs:complexType>
            <xs:sequence maxOccurs="unbounded">
                <xs:element  ref="MyCompanySubElement"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
   
    <xs:element name="MyCompanySubElement">
        <xs:complexType>
            <xs:sequence maxOccurs="unbounded">
                <xs:any namespace="http://some_namespace_here" processContents="skip"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

and this XML is valid according to the above schema

<?xml version="1.0" encoding="UTF-8"?>
<MyCompanyElement
    xmlns="urn:sunlight"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="urn:sunlight sunlight.xsd"
    xmlns:new_ns="http://some_namespace_here">
    <MyCompanySubElement>
        <new_ns:other_company_conceptual_element/>
    </MyCompanySubElement>
</MyCompanyElement>
ASKER CERTIFIED SOLUTION
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks Geert! Excellent work, by the way. :-)