private void AddIdOrIdRef(XmlElement e, XmlAttribute a, Attribute attr) { // any previous value will have been removed in NodeChanging event AttributeBinding ab; string val = a.Value; switch (attr.Type) { case AttributeType.ID: ab = new AttributeBinding(e, attr.Name, val, a.Specified); idTracker.AddId(ab); if (idTracker.IdCount(val) > 1) { foreach (AttributeBinding ab2 in idTracker.GetIdBindings(val)) { // TODO: L: inefficient, lots of removing then adding XmlAttribute a2 = ab2.Element.GetAttributeNode(ab2.Name); AttributeErrorFilter aef = new AttributeErrorFilter(ab2.Element, a2, ValidationErrorType.IdAttributeInUse); RemoveValidationErrors(aef); ValidationErrorAttribute vea = new ValidationErrorAttribute(ab2.Element, a2.Name, ValidationErrorType.IdAttributeInUse); AddValidationError(ab2.Element, vea); } } foreach (AttributeBinding ab2 in idTracker.GetIdRefBindings(val)) { XmlAttribute ar = ab.Element.GetAttributeNode(ab2.Name); AttributeErrorFilter aef = new AttributeErrorFilter(ab2.Element, ar, ValidationErrorType.IdAttributeNotDefined); RemoveValidationErrors(aef); } break; case AttributeType.IDREF: case AttributeType.IDREFS: ab = new AttributeBinding(e, attr.Name, val, a.Specified); idTracker.AddIdRefs(ab); // TODO: L: inefficient - we split twice, here and in AddIdRefs foreach (string id in ab.Value.Split(' ')) { if (idTracker.IdCount(id) == 0) { ValidationErrorAttribute vea = new ValidationErrorAttribute(e, a.Name, ValidationErrorType.IdAttributeNotDefined); AddValidationError(e, vea); } } break; } }
// private IList FilterValidNext(IList col, XmlElement n) // { // ArrayList ret=new ArrayList(); // foreach ( SimpleReference sr in col ) // { // if ( ret.Contains(sr) ) // continue; // // if ( n != null && // FindInCollection(sr.OriginalReference.GetValidNextElements(), n) != null ) // ret.Add(sr); // } // return ret; // } // private IList GetValidFirstCaseElements(ElementType et, XmlElement e) // { // ArrayList ret=new ArrayList(); // IList col=et.ContentModel.GetValidFirstElements(); // foreach ( SimpleReference sr in col ) // { // if ( ret.Contains(sr) ) // continue; // // if ( FindInCollection(sr.OriginalReference.GetValidNextElements(), e) != null ) // ret.Add(sr); // } // return ret; // } // private SimpleReference FindReference(ElementType et, XmlElement parent, XmlElement n) // { // IList col=et.ContentModel.GetValidFirstElements(); // SimpleReference r=null; // foreach ( XmlNode c in parent.ChildNodes ) // { // if ( c.NodeType != XmlNodeType.Element ) // continue; // // XmlElement child=(XmlElement) c; // // if ( child.Equals(n) ) // break; // // r=FindInCollection(col, child); // if ( r == null ) // return null; // // col=r.OriginalReference.GetValidNextElements(); // if ( col.Count == 0 ) // return null; // // r=(SimpleReference) col[0]; // } // return r; // } private void ValidateAttributeAddOrChange(XmlAttribute a) { XmlElement e = a.OwnerElement; if (documentType == null || e == null) { return; } if (e.ParentNode == null) { // node is not in document yet return; } ElementType et = documentType.GetElementType(e); if (et == null) { return; } AttributeErrorFilter aef = new AttributeErrorFilter(e, a); RemoveValidationErrors(aef); Attribute attr = et.GetAttribute(a); if (attr == null) { ValidationError ve = new ValidationErrorAttribute(e, a.Name, ValidationErrorType.AttributeNotDefined); AddValidationError(e, ve); return; } // it's only at this point we can even tell if it's ID/IDREF AddIdOrIdRef(e, a, attr); if (!validationEngine.ValidateAttribute(attr, e, a)) { ValidationError ve = new ValidationErrorAttribute(e, a.Name, ValidationErrorType.InvalidAttributeValue); AddValidationError(e, ve); } }