Question

So basically I have the problem that the key constraint I require does not get applied properly when I use element references. So for example something like this:

<xs:element ref="B" maxOccurs="unbounded"/>

note that the name of elements, attributes, namespaces and so one are just samples, they later on they will have logical names

So have an XML schema that looks like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="test" xmlns="test" elementFormDefault="qualified">  

    <xs:element name="B">
        <xs:complexType>
            <xs:attribute name="c" type="xs:string" use="required"/>
            <xs:attribute name="d" type="xs:hexBinary" use="required"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="A" >
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="B" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
        <xs:key name="bk">
            <xs:selector xpath="A/B"/>
            <xs:field xpath="@c"/>
        </xs:key>
    </xs:element>
</xs:schema>

which gets applied to the following XML file

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<A xmlns="test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="test schema.xsd">
    <B c="test0" d="0011"/>
    <B c="test1" d="2233"/>
    <B c="test1" d="4455"/>
</A>

As you can see the key constraint is bascially invalid, as there are two Bs with the same c (test1 in this case). However when validated against the schema (using visual studio 2012), this not recognise this as an error.

However when I change the XML schema to this, it works.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="test" xmlns="test" elementFormDefault="qualified">  
    <xs:element name="A" >
        <xs:complexType>
            <xs:sequence>
                <xs:element name="B" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:attribute name="c" type="xs:string" use="required"/>
                        <xs:attribute name="d" type="xs:hexBinary" use="required"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
        <xs:key name="bk">
            <xs:selector xpath="A/B"/>
            <xs:field xpath="@c"/>
        </xs:key>
    </xs:element>
</xs:schema>

So basically the element is included in A without a reference, so I assume that it has something to do with the xpath attribute of the selector of the key.

question is, how do I get this to work with a element reference, since I would like to be able to use the element reference for more complex xml structures.

EDIT:

So it seems the solution with the targetnamespace as correct after all, I just had to use it correctly one the . The following now works and indicates that the xml file is invalid:

the schema:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema targetNamespace="test" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="test" elementFormDefault="qualified">  

    <xs:element name="B">
        <xs:complexType>
            <xs:attribute name="c" type="xs:string" use="required"/>
            <xs:attribute name="d" type="xs:hexBinary" use="required"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="A" >
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="tns:B" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
        <xs:key name="bk">
            <xs:selector xpath="tns:B"/>
            <xs:field xpath="@c"/>
        </xs:key>
    </xs:element>
</xs:schema>

the xml file also used the namespace as well

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tns:A xmlns:tns="test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="test test.xsd">
    <tns:B c="a" d="0011"/>
    <tns:B c="b" d="2233"/>
    <tns:B c="a" d="4455"/>
</tns:A>
Was it helpful?

Solution

When specifying XPath elements of keys and references the namespace of the target XML will have to be included. Using the namespace tns of your example schema the XPath expression of the key definition will have to be changed to

<xs:selector xpath="tns:A/tns:B"/>

Likewise, the XPath expression of the reference definition will have to be changed to

<xs:element ref="tns:B" maxOccurs="unbounded"/>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top