tags:

views:

102

answers:

3

Hi! I have the following xsd files:

SchemaA

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://schemaA"
           elementFormDefault="qualified"
           xmlns="http://schemaA"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
 <xs:element name="Configuration">
  <xs:complexType>
            <xs:all>
                <xs:element name="StationNumber" type="xs:int">
                </xs:element>
            </xs:all>
  </xs:complexType>
 </xs:element>
</xs:schema>

SchemaB

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://schemaB"
           elementFormDefault="qualified"
           xmlns="http://schemaB" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
    <xs:attribute name="Name" type="xs:string" />
</xs:schema>

I'm trying to reference them and use them from the following XML:

<?xml version="1.0"?>
<Configuration xmlns="http://schemaA"
               xmlns:ba="http://schemaB"&gt;
    <StationNumber ba:Name="aaa">1</StationNumber>
</Configuration>

Visual Studio 2008 underlines ba:Name as error with the description: The 'http://schemaB%3AName' attribute is not declared.

Any ideas?

A: 

It needs to be able to find the XSD from the namespace and that's what it's complaining about. You can use the schemaLocation in your instance document to declare this.

Francis Upton
It's obvious that XSDs are already located even without schemaLocation, since I'm saying that I don't get any errors except from ba:Name attribute.
papadi
A: 

If element StationNumber doesn't contain an attribute in the schemaA, then <StationNumber ba:Name="...">...</StationNumber> is not valid.

Solution 1: embedd schemaB in schemaA and correctly define the attribute

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://schemaA"
           elementFormDefault="qualified"
           xmlns="http://schemaA"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
 <xs:element name="Configuration">
  <xs:complexType>
            <xs:all>
                <xs:element name="StationNumber">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="xs:int">
                                <xs:attribute name="Name" type="xs:string"/>
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>
                </xs:element>
            </xs:all>
  </xs:complexType>
 </xs:element>
</xs:schema>

Then the following XML would then be validated by NetBeans:

   <ns2:Configuration  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
       xmlns:ns2='http://schemaA'
       xsi:schemaLocation='http://schemaA file:/.../src/schemaA.xsd
       http://xml.netbeans.org/schema/schemaB file:/.../schemaB.xsd'>
              <ns2:StationNumber Name="aaa">1</ns2:StationNumber>
    </ns2:Configuration>

Solution 2: You can still have a separate schemaB to define the attribute, but you will need to import it into schemaA with ref:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://schemaA"
           elementFormDefault="qualified"
           xmlns="http://schemaA"
           xmlns:ba='http://schemaB'
           xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;

                <xs:import namespace="http://schemaB"
                 schemaLocation="schemaB.xsd"/>

 <xs:element name="Configuration">
  <xs:complexType>
            <xs:all>
                <xs:element name="StationNumber">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="xs:int">
                                 <xs:attribute ref="ba:Name"/>
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>
                </xs:element>
            </xs:all>
  </xs:complexType>
 </xs:element>
</xs:schema>

Then the XML looks like this:

<ns1:Configuration  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
   xmlns:ns1='http://schemaA'
   xmlns:ba='http://schemaB'
   xsi:schemaLocation='http://schemaA file:/.../schemaA.xsd'>
    <ns1:StationNumber ba:Name="aaa"  >1</ns1:StationNumber>
</ns1:Configuration>
ewernli
+2  A: 

This is not a two schema problem, your schemas do not match your document content. The attribute Name is not listed as one of the possible attributes on Configuration.

Just because you declare a global attribute, it does not mean you can use it wherever you want. You will either have to import one schema into the other, and specify that the attribute can occur in Configuration, as in the first answer given by ewernli above.

Or you permit any attribute from the second namespace to occur in the first schema, e.g.:

<xs:element name="Configuration">
  <xs:complexType>
    <xs:all>
        <xs:element name="StationNumber" type="xs:int"/>
    </xs:all>
    <xs:anyAttribute namespace="http://schemaB"/&gt;
  </xs:complexType>
</xs:element>

CHANGED: following the comment from ewernli below, which correctly points out that this has the additional problem that StationNumber is of a simple type. If you want to prepare the type to take attributes, you need to force it to complex:

<xs:element name="Configuration">
  <xs:complexType>
    <xs:all>
      <xs:element name="StationNumber">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="xs:int"/>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
    </xs:all>
    <xs:anyAttribute namespace="http://schemaB"/&gt;
  </xs:complexType>
</xs:element>

Now you can attach the attribute as described above.

xcut
Thanks! It's much more clear now!There is still one thing confusing me! The following xml is valid according to Visual Studio 2008. I'm 100% sure that 2nd ns is in different xsd than 1st and 1st doesn't reference 2nd. How is this xml valid? Is it some kind of Visual Studio convention and not standard xsd feature?<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:cmd="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation"> <Button cmd:Click.Command="Test"/></UserControl>
papadi
I don't know the specific schema, unfortunately, but could it be that the Button element permits any attribute from the command namespace, the same way it is shown in my sample?
xcut
I consider this impossible since Button element comes from an official Microsoft namespace regarding XAML and the other namespace comes from a framework that works as an add-on to XAML (Microsoft's new UI mark up language) which is released and installed separately and optionally. And there are may such add-ons. In XAML terminology such attributes are called 'Attached Properties'.
papadi
I was not able to make your solution work with NetBeans. I get error message "Element 'ns1:StationNumber' is a simple type, so it cannot have attributes [...] However, the attribute, 'ba:Name' was found." ? +1 anyway as it seems to work for papadi.
ewernli
I had overlooked that. I expanded the solution a bit to cover that.@papadi: Microsoft may have left attributes from any namespace open in their original schema, for example like this: <xs:anyAttribute namespace="#any"/>
xcut
NEAT!!! xcut this was exactly what I was looking for! Now I can use both schemas from one xml, without SchemaA knowing anything about the existance of SchemaB!!!<xs:anyAttribute namespace="##any"/>(you missed one #)
papadi
Pleasure: as a suggestion: could you please rename the title of your question to something like "How can I use a schema with another without them knowing about each other"? The title is a bit misleading :)
xcut