You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xerces.apache.org by Shengyou Zeng <sz...@cisco.com> on 2002/06/20 00:14:25 UTC

Does xerces2-j DOMParser enforce key constraints?

I defined the following xml schema:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.bts.com/pcsp"
xmlns="http://www.bts.com/pcsp" xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="Contact">
     <xs:complexType>
       <xs:sequence>
         <xs:element name="Name" type="xs:string"/>
         <xs:element name="Title" type="xs:string"/>
         <xs:element name="Phone" type="xs:string"/>
         <xs:element name="Email" type="xs:string"/>
       </xs:sequence>
     </xs:complexType>
     <xs:key name="ContactKey">
         <xs:selector xpath="Contact"/>
         <xs:field xpath="Name"/>
     </xs:key>
</xs:element>
<xs:element name="ListOfContacts">
     <xs:complexType>
       <xs:sequence>
         <xs:element ref="Contact" minOccurs="0" maxOccurs="unbounded"/>
       </xs:sequence>
     </xs:complexType>
</xs:element>
</xs:schema>

  and composed the following instance xml document:

<?xml version="1.0"?>
<ListOfContacts xmlns="http://www.bts.com/pcsp"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
         <Contact>
                 <Name>Joe</Name>
                 <Title>CEO</Title>
                 <Phone>18005551000</Phone>
                 <Email>jsmith@cisco.com</Email>
         </Contact>
         <Contact>
                 <Name>Joe</Name>
                 <Title>CFO</Title>
                 <Phone>18005551000</Phone>
                 <Email>jsmith@cisco.com</Email>
         </Contact>
</ListOfContacts>

then in my java code, I tried to validate the instance document against the 
schema,
using a DOMParser:



             DOMParser parser = null;
             PcspErrorHandler h = null;

             parser = new 
DOMParser();//DOMParserManager.instance().getParser();
             parser.setFeature("http://xml.org/sax/features/namespaces", true);
             parser.setFeature("http://xml.org/sax/features/validation", true);
             parser.setFeature("http://apache.org/xml/features/validation/schema", 
true);

             parser.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation",
                             "http://www.bts.com/pcsp 
http://localhost:8004/pcsp/bts.xsd");
             h = new PcspErrorHandler ();
             parser.setErrorHandler(h);
             parser.parse(new InputSource(new StringReader(xml0)));

             if (h.hasError())
             {
                 System.out.println("\nParse failed");
                 System.out.println(h.getErrorMessage());
             }
             else
             {
                 System.out.println("\nParse fine");
             }

where xml0 is the content of the instance document, and PcspErrorHandler 
implements ErrorHandler
and prints error message to stdout.

The schema defines a key, the intent of which is to make sure that each 
Contact must have a Name,
and the Names of Contacts must be unique.  In the instance document, the 
two Contacts have the same
Name.  However,  when I run my java program, the DOMParser doesn't 
complain, even though the two
Contacts have the same Name.  Moreover, when I removed the content between 
the Name tags, i.e.
<Name></Name>, the parser still doesn't complain.

What am I doing wrong?  Please help.  Thanks.

-Shengyou

Re: Does xerces2-j DOMParser enforce key constraints?

Posted by Eddie Robertsson <er...@allette.com.au>.
> Hi Eddie,
>
> I made the changes that you suggested, and it worked like a charm!


Great!

> Thanks so much.
>
> Now I have another question.  DOMParser merrily validates an xml
> instance doc that contains an empty key value (e.g., <Name></Name
> or <Name/>, while such doc crashes xsv.  The node value of the <Name>
> node in the DOM tree actually is null, as expected.  It looks like that
> xerces2-j DOMParser treats such value as an empty string, i.e., "".
> I was expecting that an empty key value would prompt a key violation.
> After all, what is the use of a key if it is empty?  But that is not 
> the case.
>
> So, except to enforce a key of string type to be non-empty by restricting
> its minLength, is there a way that uses some aspects of XML Schema's
> key constraint? 

I'm not sure about this and I couldn't find anything in the XML Schema 
spec about this. You can send an email to the W3C XML Schema mailing 
list [1] for questions like these.

Cheers,
/Eddie

[1]  xmlschema-dev@w3.org

>
>
> -Shengyou
>
> At 10:03 AM 06/21/2002 +1000, Eddie Robertsson wrote:
>
>> Hi,
>>
>>> Thanks, Eddie.  I did what you suggested too, and retested again
>>> after reading your message.  The parser still doesn't complain.
>>
>>
>> I had a closer look and I didn't realize that you used a 
>> targetNamespace for your schema. Since the selector and field 
>> elements use XPath notation you will have to declare a prefix for 
>> your namespace that you can use in the XPath expression. The reason 
>> for this is that XPath doesn't support default namespaces. See below.
>>
>>>>> <?xml version="1.0" encoding="UTF-8"?>
>>>>> <xs:schema targetNamespace="http://www.bts.com/pcsp"
>>>>> xmlns="http://www.bts.com/pcsp" 
>>>>> xmlns:xs="http://www.w3.org/2001/XMLSchema"
>>>>> elementFormDefault="qualified">
>>>>
>> You have to add a namespace declaration with a prefix for your 
>> targetNamespace as well. For example:
>>
>> xmlns:p="http://www.bts.com/pcsp"
>>
>>>>>
>>>>> <xs:element name="Contact">
>>>>>     <xs:complexType>
>>>>>       <xs:sequence>
>>>>>         <xs:element name="Name" type="xs:string"/>
>>>>>         <xs:element name="Title" type="xs:string"/>
>>>>>         <xs:element name="Phone" type="xs:string"/>
>>>>>         <xs:element name="Email" type="xs:string"/>
>>>>>       </xs:sequence>
>>>>>     </xs:complexType>
>>>>>     <xs:key name="ContactKey">
>>>>>         <xs:selector xpath="Contact"/>
>>>>>         <xs:field xpath="Name"/>
>>>>>     </xs:key>
>>>>
>> In the xpath attribute for selector and field you must use this new 
>> declared prefix on your elements:
>>
>> <xs:key name="ContactKey">
>>    <xs:selector xpath="p:Contact"/>
>>    <xs:field xpath="p:Name"/>
>> </xs:key>
>>
>>
>> Cheers,
>> /Eddie
>>
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
>> For additional commands, e-mail: xerces-j-user-help@xml.apache.org
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
> For additional commands, e-mail: xerces-j-user-help@xml.apache.org
>



---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: Does xerces2-j DOMParser enforce key constraints?

Posted by Shengyou Zeng <sz...@cisco.com>.
Hi Eddie,

I made the changes that you suggested, and it worked like a charm!
Thanks so much.

Now I have another question.  DOMParser merrily validates an xml
instance doc that contains an empty key value (e.g., <Name></Name
or <Name/>, while such doc crashes xsv.  The node value of the <Name>
node in the DOM tree actually is null, as expected.  It looks like that
xerces2-j DOMParser treats such value as an empty string, i.e., "".
I was expecting that an empty key value would prompt a key violation.
After all, what is the use of a key if it is empty?  But that is not the case.

So, except to enforce a key of string type to be non-empty by restricting
its minLength, is there a way that uses some aspects of XML Schema's
key constraint?

-Shengyou

At 10:03 AM 06/21/2002 +1000, Eddie Robertsson wrote:
>Hi,
>
>>Thanks, Eddie.  I did what you suggested too, and retested again
>>after reading your message.  The parser still doesn't complain.
>
>I had a closer look and I didn't realize that you used a targetNamespace 
>for your schema. Since the selector and field elements use XPath notation 
>you will have to declare a prefix for your namespace that you can use in 
>the XPath expression. The reason for this is that XPath doesn't support 
>default namespaces. See below.
>
>>>><?xml version="1.0" encoding="UTF-8"?>
>>>><xs:schema targetNamespace="http://www.bts.com/pcsp"
>>>>xmlns="http://www.bts.com/pcsp" xmlns:xs="http://www.w3.org/2001/XMLSchema"
>>>>elementFormDefault="qualified">
>You have to add a namespace declaration with a prefix for your 
>targetNamespace as well. For example:
>
>xmlns:p="http://www.bts.com/pcsp"
>
>>>>
>>>><xs:element name="Contact">
>>>>     <xs:complexType>
>>>>       <xs:sequence>
>>>>         <xs:element name="Name" type="xs:string"/>
>>>>         <xs:element name="Title" type="xs:string"/>
>>>>         <xs:element name="Phone" type="xs:string"/>
>>>>         <xs:element name="Email" type="xs:string"/>
>>>>       </xs:sequence>
>>>>     </xs:complexType>
>>>>     <xs:key name="ContactKey">
>>>>         <xs:selector xpath="Contact"/>
>>>>         <xs:field xpath="Name"/>
>>>>     </xs:key>
>In the xpath attribute for selector and field you must use this new 
>declared prefix on your elements:
>
><xs:key name="ContactKey">
>    <xs:selector xpath="p:Contact"/>
>    <xs:field xpath="p:Name"/>
></xs:key>
>
>
>Cheers,
>/Eddie
>
>
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
>For additional commands, e-mail: xerces-j-user-help@xml.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: Does xerces2-j DOMParser enforce key constraints?

Posted by Eddie Robertsson <er...@allette.com.au>.
Hi,

> Thanks, Eddie.  I did what you suggested too, and retested again
> after reading your message.  The parser still doesn't complain. 

I had a closer look and I didn't realize that you used a targetNamespace 
for your schema. Since the selector and field elements use XPath 
notation you will have to declare a prefix for your namespace that you 
can use in the XPath expression. The reason for this is that XPath 
doesn't support default namespaces. See below.

>>> <?xml version="1.0" encoding="UTF-8"?>
>>> <xs:schema targetNamespace="http://www.bts.com/pcsp"
>>> xmlns="http://www.bts.com/pcsp" 
>>> xmlns:xs="http://www.w3.org/2001/XMLSchema"
>>> elementFormDefault="qualified"> 
>>
You have to add a namespace declaration with a prefix for your 
targetNamespace as well. For example:

xmlns:p="http://www.bts.com/pcsp"

>>>
>>> <xs:element name="Contact">
>>>     <xs:complexType>
>>>       <xs:sequence>
>>>         <xs:element name="Name" type="xs:string"/>
>>>         <xs:element name="Title" type="xs:string"/>
>>>         <xs:element name="Phone" type="xs:string"/>
>>>         <xs:element name="Email" type="xs:string"/>
>>>       </xs:sequence>
>>>     </xs:complexType>
>>>     <xs:key name="ContactKey">
>>>         <xs:selector xpath="Contact"/>
>>>         <xs:field xpath="Name"/>
>>>     </xs:key> 
>>
In the xpath attribute for selector and field you must use this new 
declared prefix on your elements:

<xs:key name="ContactKey">
    <xs:selector xpath="p:Contact"/>
    <xs:field xpath="p:Name"/>
</xs:key>


Cheers,
/Eddie




---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: Does xerces2-j DOMParser enforce key constraints?

Posted by Shengyou Zeng <sz...@cisco.com>.
Thanks, Eddie.  I did what you suggested too, and retested again
after reading your message.  The parser still doesn't complain.

-Shengyou

At 10:01 AM 06/20/2002 +1000, Eddie Robertsson wrote:
>Hi,
>
>><?xml version="1.0" encoding="UTF-8"?>
>><xs:schema targetNamespace="http://www.bts.com/pcsp"
>>xmlns="http://www.bts.com/pcsp" xmlns:xs="http://www.w3.org/2001/XMLSchema"
>>elementFormDefault="qualified">
>><xs:element name="Contact">
>>     <xs:complexType>
>>       <xs:sequence>
>>         <xs:element name="Name" type="xs:string"/>
>>         <xs:element name="Title" type="xs:string"/>
>>         <xs:element name="Phone" type="xs:string"/>
>>         <xs:element name="Email" type="xs:string"/>
>>       </xs:sequence>
>>     </xs:complexType>
>>     <xs:key name="ContactKey">
>>         <xs:selector xpath="Contact"/>
>>         <xs:field xpath="Name"/>
>>     </xs:key>
>></xs:element>
>><xs:element name="ListOfContacts">
>>     <xs:complexType>
>>       <xs:sequence>
>>         <xs:element ref="Contact" minOccurs="0" maxOccurs="unbounded"/>
>>       </xs:sequence>
>>     </xs:complexType>
>></xs:element>
>></xs:schema>
>
>The problem is that the key is defined in the wrong place. In W3C XML 
>Schemas the key should be defined on the element which defines the scope 
>of the uniqueness (1), the selector element should select the element that 
>should be unique (2) and the field should identify the key (3). In your 
>case 1, 2 and 3 are as follows:
>
>(1) ListOfContacts
>(2) Contact
>(3) Name
>
>So, you key should be defined on the ListOfContacts element, the selector 
>should select the Contact element and the field should identify the Name 
>element:
>
><?xml version="1.0" encoding="UTF-8"?>
><xs:schema targetNamespace="http://www.bts.com/pcsp"
>xmlns="http://www.bts.com/pcsp" 
>xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
><xs:element name="Contact">
>    <xs:complexType>
>      <xs:sequence>
>        <xs:element name="Name" type="xs:string"/>
>        <xs:element name="Title" type="xs:string"/>
>        <xs:element name="Phone" type="xs:string"/>
>        <xs:element name="Email" type="xs:string"/>
>      </xs:sequence>
>    </xs:complexType>
></xs:element>
><xs:element name="ListOfContacts">
>    <xs:complexType>
>      <xs:sequence>
>        <xs:element ref="Contact" minOccurs="0" maxOccurs="unbounded"/>
>      </xs:sequence>
>    </xs:complexType>
>    <xs:key name="ContactKey">
>        <xs:selector xpath="Contact"/>
>        <xs:field xpath="Name"/>
>    </xs:key>
></xs:element>
>
>
>Cheers,
>/Eddie
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
>For additional commands, e-mail: xerces-j-user-help@xml.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org


Re: Does xerces2-j DOMParser enforce key constraints?

Posted by Eddie Robertsson <er...@allette.com.au>.
Hi,

> <?xml version="1.0" encoding="UTF-8"?>
> <xs:schema targetNamespace="http://www.bts.com/pcsp"
> xmlns="http://www.bts.com/pcsp" 
> xmlns:xs="http://www.w3.org/2001/XMLSchema"
> elementFormDefault="qualified">
> <xs:element name="Contact">
>     <xs:complexType>
>       <xs:sequence>
>         <xs:element name="Name" type="xs:string"/>
>         <xs:element name="Title" type="xs:string"/>
>         <xs:element name="Phone" type="xs:string"/>
>         <xs:element name="Email" type="xs:string"/>
>       </xs:sequence>
>     </xs:complexType>
>     <xs:key name="ContactKey">
>         <xs:selector xpath="Contact"/>
>         <xs:field xpath="Name"/>
>     </xs:key>
> </xs:element>
> <xs:element name="ListOfContacts">
>     <xs:complexType>
>       <xs:sequence>
>         <xs:element ref="Contact" minOccurs="0" maxOccurs="unbounded"/>
>       </xs:sequence>
>     </xs:complexType>
> </xs:element>
> </xs:schema>

The problem is that the key is defined in the wrong place. In W3C XML 
Schemas the key should be defined on the element which defines the scope 
of the uniqueness (1), the selector element should select the element 
that should be unique (2) and the field should identify the key (3). In 
your case 1, 2 and 3 are as follows:

(1) ListOfContacts
(2) Contact
(3) Name

So, you key should be defined on the ListOfContacts element, the 
selector should select the Contact element and the field should identify 
the Name element:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.bts.com/pcsp"
xmlns="http://www.bts.com/pcsp" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Contact">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Name" type="xs:string"/>
        <xs:element name="Title" type="xs:string"/>
        <xs:element name="Phone" type="xs:string"/>
        <xs:element name="Email" type="xs:string"/>
      </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="ListOfContacts">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Contact" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
    <xs:key name="ContactKey">
        <xs:selector xpath="Contact"/>
        <xs:field xpath="Name"/>
    </xs:key>
</xs:element>


Cheers,
/Eddie


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-j-user-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-j-user-help@xml.apache.org