sandygao 2002/10/23 16:00:52 Modified: java/src/org/apache/xerces/impl/xs XMLSchemaValidator.java Log: Fixing bugs related to PSVI properties "validity" and "validation attempted": 1. it's not invalid if an element decl/type definition can't be found for the root element. for historical reasons, we still report an error in this case, but in PSVI, the validity should be unknown. 2. if an sub-element/attribute is invalid, then the containing element should be invalid too. 3. if an element is laxly assessed, its validity should be unknown, instead of valid. 4. if an element is laxly assessed, and it doesn't have any children, its "validation attempted" should be "none", not "full". Revision Changes Path 1.117 +97 -42 xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaValidator.java Index: XMLSchemaValidator.java =================================================================== RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaValidator.java,v retrieving revision 1.116 retrieving revision 1.117 diff -u -r1.116 -r1.117 --- XMLSchemaValidator.java 21 Oct 2002 16:45:14 -0000 1.116 +++ XMLSchemaValidator.java 23 Oct 2002 23:00:51 -0000 1.117 @@ -379,6 +379,7 @@ // should be called when an attribute is done: get all errors of // this attribute, but leave the errors to the containing element + // also called after an element was strictly assessed. public String[] mergeContext() { if (!fAugPSVI) return null; @@ -1117,11 +1118,14 @@ // REVISIT: what do we store here? QName, XPATH, some ID? use rawname now. String fValidationRoot; - /** Skip validation. */ + /** Skip validation: anything below this level should be skipped */ int fSkipValidationDepth; - /** Partial validation depth */ - int fPartialValidationDepth; + /** anything above this level has validation_attempted != full */ + int fNFullValidationDepth; + + /** anything above this level has validation_attempted != none */ + int fNNoneValidationDepth; /** Element depth: -2: validator not in pipeline; >= -1 current depth. */ int fElementDepth; @@ -1168,6 +1172,12 @@ /** stack to hold content model states */ int[][] fCMStateStack = new int[INITIAL_STACK_SIZE][]; + /** whether the curret element is strictly assessed */ + boolean fStrictAssess = true; + + /** strict assess stack */ + boolean[] fStrictAssessStack = new boolean[INITIAL_STACK_SIZE]; + /** Temporary string buffers. */ final StringBuffer fBuffer = new StringBuffer(); @@ -1395,7 +1405,8 @@ fCurrentCM = null; fCurrCMState = null; fSkipValidationDepth = -1; - fPartialValidationDepth = -1; + fNFullValidationDepth = -1; + fNNoneValidationDepth = -1; fElementDepth = -1; fChildCount = 0; @@ -1503,14 +1514,18 @@ System.arraycopy(fCMStack, 0, newArrayC, 0, fElementDepth); fCMStack = newArrayC; - boolean[] newArrayD = new boolean[newSize]; - System.arraycopy(fStringContent, 0, newArrayD, 0, fElementDepth); - fStringContent = newArrayD; - - newArrayD = new boolean[newSize]; - System.arraycopy(fSawChildrenStack, 0, newArrayD, 0, fElementDepth); - fSawChildrenStack = newArrayD; - + newArrayB = new boolean[newSize]; + System.arraycopy(fStringContent, 0, newArrayB, 0, fElementDepth); + fStringContent = newArrayB; + + newArrayB = new boolean[newSize]; + System.arraycopy(fSawChildrenStack, 0, newArrayB, 0, fElementDepth); + fSawChildrenStack = newArrayB; + + newArrayB = new boolean[newSize]; + System.arraycopy(fStrictAssessStack, 0, newArrayB, 0, fElementDepth); + fStrictAssessStack = newArrayB; + int[][] newArrayIA = new int[newSize][]; System.arraycopy(fCMStateStack, 0, newArrayIA, 0, fElementDepth); fCMStateStack = newArrayIA; @@ -1764,6 +1779,7 @@ fNilStack[fElementDepth] = fNil; fNotationStack[fElementDepth] = fNotation; fTypeStack[fElementDepth] = fCurrentType; + fStrictAssessStack[fElementDepth] = fStrictAssess; fCMStack[fElementDepth] = fCurrentCM; fCMStateStack[fElementDepth] = fCurrCMState; fStringContent[fElementDepth] = fSawCharacters; @@ -1776,6 +1792,7 @@ fCurrentElemDecl = null; XSWildcardDecl wildcard = null; fCurrentType = null; + fStrictAssess = true; fNil = false; fNotation = null; @@ -1856,8 +1873,16 @@ augs = getEmptyAugs(augs); return augs; } - // report error, because it's root element - reportSchemaError("cvc-elt.1", new Object[]{element.rawname}); + // We don't call reportSchemaError here, because the spec + // doesn't think it's invalid not to be able to find a + // declaration or type definition for an element. Xerces is + // reporting it as an error for historical reasons, but in + // PSVI, we shouldn't mark this element as invalid because + // of this. - SG + fXSIErrorReporter.fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN, + "cvc-elt.1", + new Object[]{element.rawname}, + XMLErrorReporter.SEVERITY_ERROR); } // if wildcard = strict, report error else if (wildcard != null && @@ -1869,6 +1894,11 @@ // Allowed by the spec, we can choose to either laxly assess this // element, or to skip it. Now we choose lax assessment. fCurrentType = SchemaGrammar.fAnyType; + fStrictAssess = false; + fNFullValidationDepth = fElementDepth; + } + else { + fNNoneValidationDepth = fElementDepth; } // make the current element validation root @@ -2015,7 +2045,7 @@ if (fSkipValidationDepth == fElementDepth && fSkipValidationDepth > 0) { // set the partial validation depth to the depth of parent - fPartialValidationDepth = fSkipValidationDepth-1; + fNFullValidationDepth = fSkipValidationDepth-1; fSkipValidationDepth = -1; fElementDepth--; fChildCount = fChildCountStack[fElementDepth]; @@ -2024,6 +2054,7 @@ fNotation = fNotationStack[fElementDepth]; fCurrentType = fTypeStack[fElementDepth]; fCurrentCM = fCMStack[fElementDepth]; + fStrictAssess = fStrictAssessStack[fElementDepth]; fCurrCMState = fCMStateStack[fElementDepth]; fSawCharacters = fStringContent[fElementDepth]; fSawChildren = fSawChildrenStack[fElementDepth]; @@ -2090,14 +2121,10 @@ } } fValueStoreCache.endElement(); - - - // decrease element depth and restore states - fElementDepth--; SchemaGrammar[] grammars = null; // have we reached the end tag of the validation root? - if (fElementDepth == -1) { + if (fElementDepth == 0) { // 7 If the element information item is the validation root, it must be valid per Validation Root Valid (ID/IDREF) (3.3.4). String invIdRef = fValidationState.checkIDRefID(); if (invIdRef != null) { @@ -2118,6 +2145,10 @@ } else { augs = endElementPSVI(false, grammars, augs); + + // decrease element depth and restore states + fElementDepth--; + // get the states for the parent element. fChildCount = fChildCountStack[fElementDepth]; fCurrentElemDecl = fElemDeclStack[fElementDepth]; @@ -2125,12 +2156,18 @@ fNotation = fNotationStack[fElementDepth]; fCurrentType = fTypeStack[fElementDepth]; fCurrentCM = fCMStack[fElementDepth]; + fStrictAssess = fStrictAssessStack[fElementDepth]; fCurrCMState = fCMStateStack[fElementDepth]; fSawCharacters = fStringContent[fElementDepth]; fSawChildren = fSawChildrenStack[fElementDepth]; - } - + // We should have a stack for whitespace value, and pop it up here. + // But when fWhiteSpace != -1, and we see a sub-element, it must be + // an error (at least for Schema 1.0). So for valid documents, the + // only value we are going to push/pop in the stack is -1. + // Here we just mimic the effect of popping -1. -SG + fWhiteSpace = -1; + } return augs; } // handleEndElement(QName,boolean)*/ @@ -2147,35 +2184,53 @@ fCurrentPSVI.fNotation = this.fNotation; fCurrentPSVI.fValidationContext = this.fValidationRoot; // PSVI: validation attempted - if (fElementDepth <= fPartialValidationDepth) { - // the element had child with a content skip. - fCurrentPSVI.fValidationAttempted = ElementPSVI.VALIDATION_PARTIAL; - if (fElementDepth == fPartialValidationDepth) { - // set depth to the depth of the parent - fPartialValidationDepth--; - } + // nothing below or at the same level has none or partial + // (which means this level is strictly assessed, and all chidren + // are full), so this one has full + if (fElementDepth > fNFullValidationDepth) { + fCurrentPSVI.fValidationAttempted = ElementPSVI.VALIDATION_FULL; } + // nothing below or at the same level has full or partial + // (which means this level is not strictly assessed, and all chidren + // are none), so this one has none + else if (fElementDepth > fNNoneValidationDepth) { + fCurrentPSVI.fValidationAttempted = ElementPSVI.VALIDATION_NONE; + } + // otherwise partial, and anything above this level will be partial else { - fCurrentPSVI.fValidationAttempted = ElementPSVI.VALIDATION_FULL; + fCurrentPSVI.fValidationAttempted = ElementPSVI.VALIDATION_PARTIAL; + fNFullValidationDepth = fNNoneValidationDepth = fElementDepth-1; } - + if (fDefaultValue != null) fCurrentPSVI.fSpecified = true; fCurrentPSVI.fNil = fNil; fCurrentPSVI.fMemberType = fValidatedInfo.memberType; fCurrentPSVI.fNormalizedValue = fValidatedInfo.normalizedValue; - // pop error reporter context: get all errors for the current - // element, and remove them from the error list - String[] errors = fXSIErrorReporter.popContext(); - - // PSVI: error codes - fCurrentPSVI.fErrorCodes = errors; - // PSVI: validity - fCurrentPSVI.fValidity = (errors == null) ? - ElementPSVI.VALIDITY_VALID : - ElementPSVI.VALIDITY_INVALID; + if (fStrictAssess) { + // get all errors for the current element, its attribute, + // and subelements (if they were strictly assessed). + // any error would make this element invalid. + // and we merge these errors to the parent element. + String[] errors = fXSIErrorReporter.mergeContext(); + // PSVI: error codes + fCurrentPSVI.fErrorCodes = errors; + // PSVI: validity + fCurrentPSVI.fValidity = (errors == null) ? + ElementPSVI.VALIDITY_VALID : + ElementPSVI.VALIDITY_INVALID; + } + else { + // PSVI: validity + fCurrentPSVI.fValidity = ElementPSVI.VALIDITY_UNKNOWN; + // Discard the current context: ignore any error happened within + // the sub-elements/attributes of this element, because those + // errors won't affect the validity of the parent elements. + fXSIErrorReporter.popContext(); + } + if (root) { // store [schema information] in the PSVI fCurrentPSVI.fSchemaInformation = new XSModelImpl(grammars);
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]