You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-dev@xerces.apache.org by "George Cristian Bina (JIRA)" <xe...@xml.apache.org> on 2006/02/22 10:21:39 UTC

[jira] Commented: (XERCESJ-1138) More than one values for a key not detected

    [ http://issues.apache.org/jira/browse/XERCESJ-1138?page=comments#action_12367323 ] 

George Cristian Bina commented on XERCESJ-1138:
-----------------------------------------------

Hmm, looking more into the code it seems like the patch inroduces another problem. The idea is that we should ignore a matched attribute only if another Path mathed the same attribute. Currently in Xerces the mathed attribute is ignored even if a previous Path matched a differnet attribute. The proposed patch reports an attribute even if the same attribute was matched by a previous Path like in the sample below:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="test">
    <xs:complexType>
      <xs:sequence maxOccurs="unbounded">
        <xs:element ref="a"/>
      </xs:sequence>
    </xs:complexType>
    <xs:key name="aID">
      <xs:selector xpath=".//a"/>
      <xs:field xpath=".//@id1 | ./b/@id1"/>
    </xs:key>
  </xs:element>
  <xs:element name="a">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="a"/>
        <xs:element ref="b"/>        
        <xs:element ref="id1"/>
        <xs:element ref="id2"/>
        <xs:element ref="f"/>        
      </xs:choice>
      <xs:attribute name="id1" use="optional"/>
      <xs:attribute name="id2" use="optional"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="b">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="a"/>
        <xs:element ref="b"/>        
        <xs:element ref="id1"/>
        <xs:element ref="id2"/>
        <xs:element ref="f"/>        
      </xs:choice>
      <xs:attribute name="id1" use="optional"/>
      <xs:attribute name="id2" use="optional"/>
    </xs:complexType>
  </xs:element>  
  <xs:element name="id1" type="xs:string"/>
  <xs:element name="id2" type="xs:string"/>
  <xs:element name="f">
    <xs:complexType>
      <xs:attribute name="fid" fixed="fid"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

<?xml version="1.0" encoding="UTF-8"?>
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="test1.xsd">
  <a>
    <b id1="v1"></b>
  </a>
</test>

I think that the best approach will be to gather all the nodes that match in a set (thus the duplicates are removed) and at the end, when all the Paths are processed we can call the matched method on the gathered nodes.

A similar problem also exists for elements, where if we have a Path that matches on an attribute before a Path that mathes an element the element match is not notified, like in the sample below:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="test">
    <xs:complexType>
      <xs:sequence maxOccurs="unbounded">
        <xs:element ref="a"/>
      </xs:sequence>
    </xs:complexType>
    <xs:key name="aID">
      <xs:selector xpath=".//a"/>
      <xs:field xpath="./@id1|./@id2|./id1|./id2"/>
    </xs:key>
  </xs:element>
  <xs:element name="a">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="a"/>
        <xs:element ref="id1"/>
        <xs:element ref="id2"/>
      </xs:choice>
      <xs:attribute name="id1" use="optional"/>
      <xs:attribute name="id2" use="optional"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="id1" type="xs:string"/>
  <xs:element name="id2" type="xs:string"/>
</xs:schema>


<?xml version="1.0" encoding="UTF-8"?>
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd">
  <a id1="1">
    <id1>2</id1>
  </a>
</test>

Best Regards,
George

> More than one values for a key not detected
> -------------------------------------------
>
>          Key: XERCESJ-1138
>          URL: http://issues.apache.org/jira/browse/XERCESJ-1138
>      Project: Xerces2-J
>         Type: Bug
>   Components: XML Schema Structures
>     Versions: 2.7.1
>     Reporter: George Cristian Bina

>
> For a schema like below
> <?xml version="1.0" encoding="UTF-8"?>
> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
>   <xs:element name="test">
>     <xs:complexType>
>       <xs:sequence maxOccurs="unbounded">
>         <xs:element ref="a"/>
>       </xs:sequence>
>     </xs:complexType>
>     <xs:key name="aID">
>       <xs:selector xpath=".//a"/>
>       <xs:field xpath="./@id1|./@id2"/>
>     </xs:key>
>   </xs:element>
>   <xs:element name="a">
>     <xs:complexType>
>       <xs:choice minOccurs="0" maxOccurs="unbounded">
>         <xs:element ref="a"/>
>         <xs:element ref="id1"/>
>         <xs:element ref="id2"/>
>       </xs:choice>
>       <xs:attribute name="id1" use="optional"/>
>       <xs:attribute name="id2" use="optional"/>
>     </xs:complexType>
>   </xs:element>
>   <xs:element name="id1" type="xs:string"/>
>   <xs:element name="id2" type="xs:string"/>
> </xs:schema> 
> Xerces reports the following document as valid:
> <test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd">
>   <a id2="v1" id1="v2"></a>
> </test> 
> Instead of signaling the duplicate key value error:
> SystemID: E:\workspace\oXygen\samples\test.xml
> Location: 2:24
> Description: E Identity constraint error:  field "./@id1|./@id2" matches more than one value within the scope of its selector; fields must match unique values.
> The problem is in XPathMatcher when a Path matches an attribute the matched() method is not called if there is a preceding path that was matched, in this case the matched method will be called only for the first Path ./@id1 and not for the second Path ./@id2.
> Here it is the relevant code in the XPathMatcher class:
>                            if (fCurrentStep[i] == steps.length) {
>                                 fMatched[i] = MATCHED_ATTRIBUTE;
>                                 int j=0;
>                                 for(; j<i && ((fMatched[j] & MATCHED) != MATCHED); j++);
>                                 if(j==i) {
>                                     AttributePSVI attrPSVI = (AttributePSVI)attributes.getAugmentations(aIndex).getItem(Constants.ATTRIBUTE_PSVI);
>                                     fMatchedString = attrPSVI.getActualNormalizedValue();
>                                     matched(fMatchedString, attrPSVI.getActualNormalizedValueType(), attrPSVI.getItemValueTypes(), false);
>                                 }
>                             }
>                             
> The matched method should be always called to allow the detection of the duplicate value that is performed in the XMLSchemaValidator (in the ValueStore). So the above code should be replaced with"
>                             if (fCurrentStep[i] == steps.length) {
>                                 fMatched[i] = MATCHED_ATTRIBUTE;
>                                 AttributePSVI attrPSVI = (AttributePSVI)attributes.getAugmentations(aIndex).getItem(Constants.ATTRIBUTE_PSVI);
>                                 fMatchedString = attrPSVI.getActualNormalizedValue();
>                                 matched(fMatchedString, attrPSVI.getActualNormalizedValueType(), attrPSVI.getItemValueTypes(), false);
>                             }
>                            
> Best Regards,
> George

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


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