Hello everyone -
I downloaded the most recent code snapshot to test the behavior of Xerces
for the key/keyref identity constraints defined in the following
schema.
The schema:
<xs:element
name="capabilities">
<xs:complexType>
<xs:sequence>
<xs:element
ref="capability" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element
name="capability" type="capabilityType">
<xs:key
name="taskKey">
<xs:selector
xpath="./tasks/task"/>
<xs:field
xpath="@serviceid"/>
<xs:field
xpath="@taskid"/>
</xs:key>
<xs:keyref
name="defaultTaskRef" refer="taskKey">
<xs:selector
xpath=".//defaultTask"/>
<xs:field
xpath="@serviceid"/>
<xs:field
xpath="@taskid"/>
</xs:keyref>
</xs:element>
An abbreviated view of the document to be validated:
<capabilities>
<capability serviceid="1">
<explanation>
<title>Home</title>
<description>home</description>
</explanation>
...
<tasks>
<task taskid="currentEvents"
serviceid="1"/>
<task taskid="latestNews" serviceid="1"/>
<task taskid="aboutUs" serviceid="1"/>
<task taskid="homelink" serviceid="1"/>
</tasks>
<defaultTask taskid="homelink"
serviceid="1" />
...
</capability>
<capability serviceid="2">
<explanation>
<title>Monthly Abstracts</title>
<description>Reviews of the most recent articles for the
crosscut community</description>
</explanation>
...
<tasks>
<task taskid="viewAbstract"
serviceid="2"/>
</tasks>
<defaultTask taskid="viewAbstract"
serviceid="2" />
...
</capability>
</capabilities>
The output reports the following:
[Error] sampleSession.xml:319:16: Key with value [ID
Value: 1,ID Value: homelink] not found for identity
constraint of element "capability".
with the following stack trace:
org.xml.sax.SAXParseException: Key with value [ID
Value: 1,ID Value: homelink] not found for identity
constraint of element "capability".
at
org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:232)
at
org.apache.xerces.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:173)
at
org.apache.xerces.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:362)
at
org.apache.xerces.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:296)
at
org.apache.xerces.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:344)
at
org.apache.xerces.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3066)
at
org.apache.xerces.impl.xs.XMLSchemaValidator$KeyRefValueStore.endDocumentFragment(XMLSchemaValidator.java:3577)
at
org.apache.xerces.impl.xs.XMLSchemaValidator.handleEndElement(XMLSchemaValidator.java:1988)
at
org.apache.xerces.impl.xs.XMLSchemaValidator.endElement(XMLSchemaValidator.java:694)
at
org.apache.xerces.impl.XMLNamespaceBinder.handleEndElement(XMLNamespaceBinder.java:853)
at
org.apache.xerces.impl.XMLNamespaceBinder.endElement(XMLNamespaceBinder.java:643)
at
org.apache.xerces.impl.dtd.XMLDTDValidator.handleEndElement(XMLDTDValidator.java:2978)
at
org.apache.xerces.impl.dtd.XMLDTDValidator.endElement(XMLDTDValidator.java:918)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.handleEndElement(XMLDocumentFragmentScannerImpl.java:1145)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:988)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(XMLDocumentFragmentScannerImpl.java:1446)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:333)
at
org.apache.xerces.parsers.StandardParserConfiguration.parse(StandardParserConfiguration.java:529)
at
org.apache.xerces.parsers.StandardParserConfiguration.parse(StandardParserConfiguration.java:585)
at
org.apache.xerces.parsers.XMLParser.parse(XMLParser.java:147)
at
org.apache.xerces.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1087)
Line 319 in the actual xml file corresponds to the
</capability> tag for <capability
serviceid="2">. My understanding is that the keyref
constraint for [ID Value: 1,ID Value:
homelink] should go out of scope at the corresponding end element
tag for <capability serviceid="1">, just as the
ValueStore object for the valid key values is purged of those values at
the end-element processing for that element.
I found that making the following change to XMLSchemaValidator.java
(rev. 1.49) produces the correct behavior within this scenario.
However, I would like to confirm that my understanding of the expected
behavior is accurate and determine if the change is valid across
key/keyref scenarios.
Augmentations handleEndElement(QName element, Augmentations augs) {
<snip> to line 1967
// now handle
keyref's/...
for (int i = oldCount - 1; i
>= newCount; i--) {
XPathMatcher matcher = fMatcherStack.getMatcherAt(i);
IdentityConstraint id;
if
((id = matcher.getIDConstraint()) != null && id.getType() ==
IdentityConstraint.KEYREF) {
ValueStoreBase values = fValueStoreCache.getValueStoreFor(id);
if (values != null){ // nothing to do if nothing matched!
values.endDocumentFragment();
values.destroy();
//03/21/02 added to correctly update the scope of keyrefs
}
matcher.endDocumentFragment();
}
}
<snip> to end of method
} // handleEndElement(QName,boolean)*/
Any insight, suggestions or confirmation would be greatly
appreciated.
Thanks,
Rebekah