public int PushKS(int errline, int errcol) { KSStruct struct2; KeySequence ks = new KeySequence(this.cs.TableDim, errline, errcol); if (this.KSpointer < this.KSs.Count) { struct2 = (KSStruct) this.KSs[this.KSpointer]; struct2.ks = ks; for (int i = 0; i < this.cs.TableDim; i++) { struct2.fields[i].Reactivate(ks); } } else { struct2 = new KSStruct(ks, this.cs.TableDim); for (int j = 0; j < this.cs.TableDim; j++) { struct2.fields[j] = new LocatedActiveAxis(this.cs.constraint.Fields[j], ks, j); this.cs.axisFields.Add(struct2.fields[j]); } this.KSs.Add(struct2); } struct2.depth = base.CurrentDepth - 1; return this.KSpointer++; }
internal void Reactivate(KeySequence ks) { Reactivate(); this.Ks = ks; }
internal LocatedActiveAxis (Asttree astfield, KeySequence ks, int column) : base (astfield) { this.Ks = ks; this.column = column; this.isMatched = false; }
public LocatedActiveAxis[] fields; // array of fields activeaxis when it matches and assigned public KSStruct(KeySequence ks, int dim) { this.ks = ks; this.fields = new LocatedActiveAxis[dim]; }
// update constraintStruct.axisFields as well, if it's new LocatedActiveAxis public int PushKS (int errline, int errcol) { // new KeySequence each time KeySequence ks = new KeySequence(cs.TableDim, errline, errcol); // needs to clear KSStruct before using KSStruct kss; if (KSpointer < KSs.Count) { // reuse, clear up KSs.KSpointer kss = (KSStruct) KSs[KSpointer]; kss.ks = ks; // reactivate LocatedActiveAxis for (int i = 0; i < cs.TableDim; i ++) { kss.fields[i].Reactivate(ks); // reassociate key sequence } } else { // "==", new kss = new KSStruct(ks, cs.TableDim); for (int i = 0; i < cs.TableDim; i ++) { kss.fields[i] = new LocatedActiveAxis (cs.constraint.Fields[i], ks, i); cs.axisFields.Add (kss.fields[i]); // new, add to axisFields } KSs.Add(kss); } kss.depth = this.CurrentDepth - 1; return (KSpointer ++); }
internal int AddToTable (KeySequence ks) { this.constraintTable.Add(ks); return (this.currentRow ++); }
private void ProcessElement() { int count = reader.AttributeCount; XmlQualifiedName xsiType = XmlQualifiedName.Empty; if (reader.Depth == 0 && SchemaInfo.SchemaType != SchemaType.DTD && validationFlag != ValidationType.DTD && validationFlag != ValidationType.None) { LoadSchema(string.Empty, null); } string[] xsiSchemaLocation = null; string xsiNoNamespaceSchemaLocation = null; string xsiNil = null; if (SchemaInfo.SchemaType != SchemaType.DTD && validationFlag != ValidationType.DTD && validationFlag != ValidationType.None) { for (int i = 0; i < count ; i++) { reader.MoveToAttribute(i); string objectNs = reader.NamespaceURI; string objectName = reader.LocalName; if (Ref.Equal(objectNs, schemaNames.NsXmlNs)) { LoadSchema(reader.Value, null); if (isProcessContents) { nsManager.AddNamespace(reader.Prefix == string.Empty ? string.Empty : reader.LocalName, reader.Value); } } else if ((validationFlag != ValidationType.XDR) && Ref.Equal(objectNs, schemaNames.NsXsi)) { if (Ref.Equal(objectName, schemaNames.XsiSchemaLocation)) { xsiSchemaLocation = (string[])dtStringArray.ParseValue(reader.Value, nameTable, nsManager); } else if (Ref.Equal(objectName, schemaNames.XsiNoNamespaceSchemaLocation)) { xsiNoNamespaceSchemaLocation = reader.Value; } else if (Ref.Equal(objectName, schemaNames.XsiType)) { xsiType = (XmlQualifiedName)dtQName.ParseValue(reader.Value, nameTable, nsManager); } else if (Ref.Equal(objectName, schemaNames.XsiNil)) { xsiNil = reader.Value; } SchemaInfo.SchemaType = SchemaType.XSD; } else if ( SchemaInfo.SchemaType != SchemaType.XSD && Ref.Equal(objectNs, schemaNames.QnDtDt.Namespace) && Ref.Equal(objectName, schemaNames.QnDtDt.Name) ) { reader.SchemaTypeObject = XmlSchemaDatatype.FromXdrName(reader.Value); SchemaInfo.SchemaType = SchemaType.XDR; } } } if (count > 0) { reader.MoveToElement(); } if (xsiNoNamespaceSchemaLocation != null) { LoadSchema(string.Empty, xsiNoNamespaceSchemaLocation); } if (xsiSchemaLocation != null) { for (int i = 0; i < xsiSchemaLocation.Length - 1; i += 2) { LoadSchema((string)xsiSchemaLocation[i], (string)xsiSchemaLocation[i + 1]); } } if (HasSchema) { if (processContents == XmlSchemaContentProcessing.Skip) { nextElement = null; } else { nextElement = SchemaInfo.GetElementDecl(this.name, (context != null) ? context.ElementDecl : null); if (nextElement != null) { if (xsiType.IsEmpty) { if (nextElement.IsAbstract) { SendValidationEvent(Res.Sch_AbstractElement, this.name.ToString()); nextElement = null; } } else if(xsiNil != null && xsiNil.Equals("true")) { SendValidationEvent(Res.Sch_XsiNilAndType); } else { SchemaElementDecl nextElementXsi = (SchemaElementDecl)SchemaInfo.ElementDeclsByType[xsiType]; if (nextElementXsi == null && xsiType.Namespace == schemaNames.NsXsd) { XmlSchemaDatatype datatype = XmlSchemaDatatype.FromTypeName(xsiType.Name); if (datatype != null) { nextElementXsi = new SchemaElementDecl(datatype, this.schemaNames); } } if (nextElementXsi == null) { SendValidationEvent(Res.Sch_XsiTypeNotFound, xsiType.ToString()); nextElement = null; } else if (!XmlSchemaType.IsDerivedFrom( (nextElementXsi.SchemaType == null ? (object)nextElementXsi.Datatype : (object)nextElementXsi.SchemaType), (nextElement.SchemaType == null ? (object)nextElement.Datatype : (object)nextElement.SchemaType), nextElement.Block )) { SendValidationEvent(Res.Sch_XsiTypeBlocked, this.name.ToString()); nextElement = null; } else { nextElement = nextElementXsi; } } } } PushElementDecl(this.name.Namespace, reader.Prefix, reader.Depth); if (context.ElementDecl != null || SchemaInfo.SchemaType == SchemaType.XSD) { if (context.ElementDecl != null && context.ElementDecl.IsNillable) { if (xsiNil != null) { context.IsNill = XmlConvert.ToBoolean(xsiNil); if (context.IsNill && context.ElementDecl.DefaultValueTyped != null) { SendValidationEvent(Res.Sch_XsiNilAndFixed); } } } else if (xsiNil != null) { SendValidationEvent(Res.Sch_InvalidXsiNill); } if (context.ElementDecl != null) { if (context.ElementDecl.SchemaType != null) { reader.SchemaTypeObject = context.ElementDecl.SchemaType; } else { reader.SchemaTypeObject = context.ElementDecl.Datatype; } if (reader.IsEmptyElement && !context.IsNill && context.ElementDecl.DefaultValueTyped != null) { reader.TypedValueObject = context.ElementDecl.DefaultValueTyped; context.IsNill = true; // reusing IsNill } if (this.context.ElementDecl.HasRequiredAttribute || this.startIDConstraint != -1) { attPresence.Clear(); } } //foreach constraint in stack (including the current one) if (this.startIDConstraint != -1) { for (int i = this.startIDConstraint; i < this.validationStack.Length; i ++) { // no constraint for this level if (((ValidationState)(this.validationStack[i])).Constr == null) { continue; } // else foreach (ConstraintStruct conuct in ((ValidationState)(this.validationStack[i])).Constr) { // check selector from here if (conuct.axisSelector.MoveToStartElement(reader.LocalName, reader.NamespaceURI)) { // selector selects new node, activate a new set of fields Debug.WriteLine("Selector Match!"); Debug.WriteLine("Name: " + reader.LocalName + "\t|\tURI: " + reader.NamespaceURI + "\n"); KeySequence ks = new KeySequence (conuct.TableDim, positionInfo.LineNumber, positionInfo.LinePosition); int row = conuct.AddToTable (ks); // new line in table assigned to this set of fields int column = 0; foreach (Asttree field in conuct.constraint.Fields) { LocatedActiveAxis laxis = new LocatedActiveAxis (field, row, column ++); conuct.axisFields.Add (laxis); } } // axisFields is not null, but may be empty foreach (LocatedActiveAxis laxis in conuct.axisFields) { // check field from here if (laxis.MoveToStartElement(reader.LocalName, reader.NamespaceURI)) { Debug.WriteLine("Element Field Match!"); // checking simpleType / simpleContent if (nextElement != null) { // nextElement can be null when xml/xsd are not valid if (nextElement.Datatype == null) { SendValidationEvent (Res.Sch_FieldSimpleTypeExpected, reader.LocalName); } else { // can't fill value here, wait till later.... // fill type : xsdType laxis.isMatched = true; // since it's simpletyped element, the endchildren will come consequently... don't worry } } } } } } } for (int i = 0; i < count ; i++) { reader.MoveToAttribute(i); if ((SchemaInfo.SchemaType == SchemaType.XSD || SchemaInfo.SchemaType == SchemaType.XDR) && (object)reader.NamespaceURI == (object)schemaNames.NsXmlNs) { continue; } if (SchemaInfo.SchemaType == SchemaType.XSD && (object)reader.NamespaceURI == (object)schemaNames.NsXsi) { continue; } this.name = QualifiedName(reader.Prefix, reader.LocalName, reader.NamespaceURI); try { bool skip; attnDef = SchemaInfo.GetAttribute(context.ElementDecl, this.name, out skip); if (attnDef != null) { if (context.ElementDecl != null && (context.ElementDecl.HasRequiredAttribute || this.startIDConstraint != -1)) { attPresence.Add(attnDef.Name, attnDef); } reader.SchemaTypeObject = (attnDef.SchemaType != null) ? (object)attnDef.SchemaType : (object)attnDef.Datatype; if (attnDef.Datatype != null) { // VC constraint: // The standalone document declaration must have the value "no" if any external markup declarations // contain declarations of attributes with values subject to normalization, where the attribute appears in // the document with a value which will change as a result of normalization, string attributeValue = reader.Value; if (reader.StandAlone && attnDef.IsDeclaredInExternal && attributeValue != reader.RawValue) { SendValidationEvent(Res.Sch_StandAloneNormalization, reader.Name); } // need to check the contents of this attribute to make sure // it is valid according to the specified attribute type. CheckValue(attributeValue, attnDef); } } else if (ValidationFlag == ValidationType.Schema && !skip) { SendValidationEvent(Res.Sch_NoAttributeSchemaFound, this.name.ToString(), XmlSeverityType.Warning); } } catch (XmlSchemaException e) { e.SetSource(reader.BaseURI, positionInfo.LineNumber, positionInfo.LinePosition); SendValidationEvent(e); } // for all constraint in the stack, i have to check this thing IDCCheckAttr(reader.LocalName, reader.NamespaceURI, reader.TypedValueObject, reader.Value, attnDef); } if (count > 0) { reader.MoveToElement(); } // Add default attributes if ( nextElement != null) { foreach (SchemaAttDef attdef in nextElement.AttDefs.Values) { if (attdef.Presence == SchemaDeclBase.Use.Default || attdef.Presence == SchemaDeclBase.Use.Fixed) { // VC constraint: // Standalone must be = "no" when any external markup declarations contain declarations of attributes // with default values, if elements to which these attributes apply appear in the document without // specifications of values for these attributes // for default attribute i have to check too... if (reader.AddDefaultAttribute(attdef) && reader.StandAlone && attdef.IsDeclaredInExternal) { SendValidationEvent(Res.Sch_UnSpecifiedDefaultAttributeInExternalStandalone, attdef.Name.Name); } // even default attribute i have to move to... but can't exist if (! attPresence.Contains(attdef.Name)) { IDCCheckAttr(attdef.Name.Name, attdef.Name.Namespace, attdef.DefaultValueTyped, attdef.DefaultValueRaw, attdef); } } } } } BeginChildren(); if (reader.IsEmptyElement) { EndChildren(); } } else { //couldnt find any schema for this element if( ValidationFlag == ValidationType.DTD && 0 == reader.Depth) { // this warning only needs to be on the documentElement SendValidationEvent(Res.Xml_NoDTDPresent, this.name.ToString(), XmlSeverityType.Warning); } else if(ValidationFlag == ValidationType.Schema) { SendValidationEvent(Res.Sch_NoElementSchemaFound, this.name.ToString(),XmlSeverityType.Warning); for (int i = 0; i < count ; i++) { reader.MoveToAttribute(i); if ((object)reader.NamespaceURI == (object)schemaNames.NsXmlNs ||(ValidationType.Schema == ValidationFlag && (object)reader.NamespaceURI == (object)schemaNames.NsXsi)) { continue; } this.name = QualifiedName(reader.Prefix, reader.LocalName, reader.NamespaceURI); SendValidationEvent(Res.Sch_NoAttributeSchemaFound, this.name.ToString(), XmlSeverityType.Warning); } reader.MoveToElement(); } } }
internal LocatedActiveAxis(Asttree astfield, KeySequence ks, int column) : base(astfield) { this.Ks = ks; this.column = column; this.isMatched = false; }
private void EndElementIdentityConstraints() { for (int ci = _validationStack.Length - 1; ci >= _startIDConstraint; ci--) { // no constraint for this level if (((ValidationState)(_validationStack[ci])).Constr == null) { continue; } // else ConstraintStruct[] constraints = ((ValidationState)_validationStack[ci]).Constr; for (int i = 0; i < constraints.Length; ++i) { // EndChildren // axisFields is not null, but may be empty for (int j = 0; j < constraints[i].axisFields.Count; ++j) { LocatedActiveAxis laxis = (LocatedActiveAxis)constraints[i].axisFields[j]; // check field from here // isMatched is false when nextElement is null. so needn't change this part. if (laxis.isMatched) { Debug.WriteLine("Element Field Filling Value!"); Debug.WriteLine("Name: " + reader.LocalName + "\t|\tURI: " + reader.NamespaceURI + "\t|\tValue: " + reader.TypedValueObject + "\n"); // fill value laxis.isMatched = false; if (laxis.Ks[laxis.Column] != null) { // [field...] should be evaluated to either an empty node-set or a node-set with exactly one member // two matches... already existing field value in the table. SendValidationEvent(SR.Sch_FieldSingleValueExpected, reader.LocalName); } else { // for element, reader.Value = ""; string stringValue = !hasSibling ? textString : textValue.ToString(); // only for identity-constraint exception reporting if (reader.TypedValueObject != null && stringValue.Length != 0) { laxis.Ks[laxis.Column] = new TypedObject(reader.TypedValueObject, stringValue, context.ElementDecl.Datatype); } } } // EndChildren laxis.EndElement(reader.LocalName, reader.NamespaceURI); } if (constraints[i].axisSelector.EndElement(reader.LocalName, reader.NamespaceURI)) { // insert key sequence into hash (+ located active axis tuple leave for later) KeySequence ks = constraints[i].axisSelector.PopKS(); // unqualified keysequence are not allowed switch (constraints[i].constraint.Role) { case CompiledIdentityConstraint.ConstraintRole.Key: if (!ks.IsQualified()) { //Key's fields can't be null... if we can return context node's line info maybe it will be better //only keymissing & keyduplicate reporting cases are necessary to be dealt with... 3 places... SendValidationEvent(new XmlSchemaException(SR.Sch_MissingKey, constraints[i].constraint.name.ToString(), reader.BaseURI, ks.PosLine, ks.PosCol)); } else if (constraints[i].qualifiedTable.Contains(ks)) { // unique or key checking value confliction // for redundant key, reporting both occurings // doesn't work... how can i retrieve value out?? SendValidationEvent(new XmlSchemaException(SR.Sch_DuplicateKey, new string[2] { ks.ToString(), constraints[i].constraint.name.ToString() }, reader.BaseURI, ks.PosLine, ks.PosCol)); } else { constraints[i].qualifiedTable.Add(ks, ks); } break; case CompiledIdentityConstraint.ConstraintRole.Unique: if (!ks.IsQualified()) { continue; } if (constraints[i].qualifiedTable.Contains(ks)) { // unique or key checking confliction SendValidationEvent(new XmlSchemaException(SR.Sch_DuplicateKey, new string[2] { ks.ToString(), constraints[i].constraint.name.ToString() }, reader.BaseURI, ks.PosLine, ks.PosCol)); } else { constraints[i].qualifiedTable.Add(ks, ks); } break; case CompiledIdentityConstraint.ConstraintRole.Keyref: // is there any possibility: // 2 keyrefs: value is equal, type is not // both put in the hashtable, 1 reference, 1 not if (constraints[i].qualifiedTable != null) { //Will be null in cases when the keyref is outside the scope of the key, that is not allowed by our impl if (!ks.IsQualified() || constraints[i].qualifiedTable.Contains(ks)) { continue; } constraints[i].qualifiedTable.Add(ks, ks); } break; } } } } // current level's constraint struct ConstraintStruct[] vcs = ((ValidationState)(_validationStack[_validationStack.Length - 1])).Constr; if (vcs != null) { // validating all referencing tables... for (int i = 0; i < vcs.Length; ++i) { if ((vcs[i].constraint.Role == CompiledIdentityConstraint.ConstraintRole.Keyref) || (vcs[i].keyrefTable == null)) { continue; } foreach (KeySequence ks in vcs[i].keyrefTable.Keys) { if (!vcs[i].qualifiedTable.Contains(ks)) { SendValidationEvent(new XmlSchemaException(SR.Sch_UnresolvedKeyref, new string[2] { ks.ToString(), vcs[i].constraint.name.ToString() }, reader.BaseURI, ks.PosLine, ks.PosCol)); } } } } }