private void ProcessLax(Choice c, string ns) { foreach (Particle p in c.Items) { Element el = p as Element; if (el == null) { throw Error(c, String.Format("Target schema item contains unacceptable particle {0}. Only element is allowed here.")); } if (ElementMatches(el, ns)) { InferElement(el, ns, false); return; } } // append a new element particle to lax term. Element nel = new Element(); if (source.NamespaceURI == ns) { nel.Name = source.LocalName; } else { nel.RefName = new QName(source.LocalName, source.NamespaceURI); AddImport(ns, source.NamespaceURI); } InferElement(nel, source.NamespaceURI, true); c.Items.Add(nel); }
internal override XmlSchemaParticle GetOptimizedParticle(bool isTop) { if (OptimizedParticle != null) { return(OptimizedParticle); } if (Items.Count == 0 || ValidatedMaxOccurs == 0) { OptimizedParticle = XmlSchemaParticle.Empty; } // LAMESPEC: Regardless of isTop, it should remove pointless particle. It seems ContentTypeParticle design bug. else if (!isTop && Items.Count == 1 && ValidatedMinOccurs == 1 && ValidatedMaxOccurs == 1) { OptimizedParticle = ((XmlSchemaParticle)Items [0]).GetOptimizedParticle(false); } else { XmlSchemaChoice c = new XmlSchemaChoice(); CopyInfo(c); for (int i = 0; i < Items.Count; i++) { XmlSchemaParticle p = Items [i] as XmlSchemaParticle; p = p.GetOptimizedParticle(false); if (p == XmlSchemaParticle.Empty) { continue; } else if (p is XmlSchemaChoice && p.ValidatedMinOccurs == 1 && p.ValidatedMaxOccurs == 1) { XmlSchemaChoice pc = p as XmlSchemaChoice; for (int ci = 0; ci < pc.Items.Count; ci++) { c.Items.Add(pc.Items [ci]); c.CompiledItems.Add(pc.Items [ci]); } } else { c.Items.Add(p); c.CompiledItems.Add(p); } } if (c.Items.Count == 0) { OptimizedParticle = XmlSchemaParticle.Empty; } else { OptimizedParticle = c; } } return(OptimizedParticle); }
private void InferComplexContent(Element el, string ns, bool isNew) { ComplexType ct = ToComplexType(el); ToComplexContentType(ct); int position = 0; bool consumed = false; do { switch (source.NodeType) { case XmlNodeType.Element: Sequence s = PopulateSequence(ct); Choice c = s.Items.Count > 0 ? s.Items [0] as Choice : null; if (c != null) { ProcessLax(c, ns); } else { ProcessSequence(ct, s, ns, ref position, ref consumed, isNew); } source.MoveToContent(); break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: MarkAsMixed(ct); source.ReadString(); source.MoveToContent(); break; case XmlNodeType.EndElement: return; // finished case XmlNodeType.None: throw new NotImplementedException("Internal Error: Should not happen."); } } while (true); }
// Note that it does not return the changed sequence. private Choice ToSequenceOfChoice(Sequence s) { Choice c = new Choice(); if (laxOccurrence) { c.MinOccurs = 0; } c.MaxOccursString = "unbounded"; foreach (Particle p in s.Items) { c.Items.Add(p); } s.Items.Clear(); s.Items.Add(c); return(c); }
internal override bool ValidateDerivationByRestriction(XmlSchemaParticle baseParticle, ValidationEventHandler h, XmlSchema schema, bool raiseError) { XmlSchemaAny any = baseParticle as XmlSchemaAny; if (any != null) { // NSRecurseCheckCardinality return(ValidateNSRecurseCheckCardinality(any, h, schema, raiseError)); } XmlSchemaChoice choice = baseParticle as XmlSchemaChoice; if (choice != null) { // RecurseLax if (!ValidateOccurenceRangeOK(choice, h, schema, raiseError)) { return(false); } // If it is totally optional, then ignore their contents. if (choice.ValidatedMinOccurs == 0 && choice.ValidatedMaxOccurs == 0 && this.ValidatedMinOccurs == 0 && this.ValidatedMaxOccurs == 0) { return(true); } // return ValidateRecurseLax (choice, h, schema, raiseError); return(this.ValidateSeqRecurseMapSumCommon(choice, h, schema, true, false, raiseError)); } if (raiseError) { error(h, "Invalid choice derivation by restriction was found."); } return(false); }
//<choice // id = ID // maxOccurs = (nonNegativeInteger | unbounded) : 1 // minOccurs = nonNegativeInteger : 1 // {any attributes with non-schema namespace . . .}> // Content: (annotation?, (element | group | choice | sequence | any)*) //</choice> internal static XmlSchemaChoice Read(XmlSchemaReader reader, ValidationEventHandler h) { XmlSchemaChoice choice = new XmlSchemaChoice(); reader.MoveToElement(); if (reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname) { error(h, "Should not happen :1: XmlSchemaChoice.Read, name=" + reader.Name, null); reader.SkipToEnd(); return(null); } choice.LineNumber = reader.LineNumber; choice.LinePosition = reader.LinePosition; choice.SourceUri = reader.BaseURI; while (reader.MoveToNextAttribute()) { if (reader.Name == "id") { choice.Id = reader.Value; } else if (reader.Name == "maxOccurs") { try { choice.MaxOccursString = reader.Value; } catch (Exception e) { error(h, reader.Value + " is an invalid value for maxOccurs", e); } } else if (reader.Name == "minOccurs") { try { choice.MinOccursString = reader.Value; } catch (Exception e) { error(h, reader.Value + " is an invalid value for minOccurs", e); } } else if ((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace) { error(h, reader.Name + " is not a valid attribute for choice", null); } else { XmlSchemaUtil.ReadUnhandledAttribute(reader, choice); } } reader.MoveToElement(); if (reader.IsEmptyElement) { return(choice); } // Content: (annotation?, (element | group | choice | sequence | any)*) int level = 1; while (reader.ReadNextElement()) { if (reader.NodeType == XmlNodeType.EndElement) { if (reader.LocalName != xmlname) { error(h, "Should not happen :2: XmlSchemaChoice.Read, name=" + reader.Name, null); } break; } if (level <= 1 && reader.LocalName == "annotation") { level = 2; //Only one annotation XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader, h); if (annotation != null) { choice.Annotation = annotation; } continue; } if (level <= 2) { if (reader.LocalName == "element") { level = 2; XmlSchemaElement element = XmlSchemaElement.Read(reader, h); if (element != null) { choice.items.Add(element); } continue; } if (reader.LocalName == "group") { level = 2; XmlSchemaGroupRef group = XmlSchemaGroupRef.Read(reader, h); if (group != null) { choice.items.Add(group); } continue; } if (reader.LocalName == "choice") { level = 2; XmlSchemaChoice ch = XmlSchemaChoice.Read(reader, h); if (ch != null) { choice.items.Add(ch); } continue; } if (reader.LocalName == "sequence") { level = 2; XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader, h); if (sequence != null) { choice.items.Add(sequence); } continue; } if (reader.LocalName == "any") { level = 2; XmlSchemaAny any = XmlSchemaAny.Read(reader, h); if (any != null) { choice.items.Add(any); } continue; } } reader.RaiseInvalidElementError(); } return(choice); }
//From the Errata //<group // id = ID // name = NCName // {any attributes with non-schema namespace . . .}> // Content: (annotation?, (all | choice | sequence)?) //</group> internal static XmlSchemaGroup Read(XmlSchemaReader reader, ValidationEventHandler h) { XmlSchemaGroup group = new XmlSchemaGroup(); reader.MoveToElement(); if (reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname) { error(h, "Should not happen :1: XmlSchemaGroup.Read, name=" + reader.Name, null); reader.Skip(); return(null); } group.LineNumber = reader.LineNumber; group.LinePosition = reader.LinePosition; group.SourceUri = reader.BaseURI; while (reader.MoveToNextAttribute()) { if (reader.Name == "id") { group.Id = reader.Value; } else if (reader.Name == "name") { group.name = reader.Value; } else if ((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace) { error(h, reader.Name + " is not a valid attribute for group", null); } else { XmlSchemaUtil.ReadUnhandledAttribute(reader, group); } } reader.MoveToElement(); if (reader.IsEmptyElement) { return(group); } // Content: (annotation?, (all | choice | sequence)?) int level = 1; while (reader.ReadNextElement()) { if (reader.NodeType == XmlNodeType.EndElement) { if (reader.LocalName != xmlname) { error(h, "Should not happen :2: XmlSchemaGroup.Read, name=" + reader.Name, null); } break; } if (level <= 1 && reader.LocalName == "annotation") { level = 2; //Only one annotation XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader, h); if (annotation != null) { group.Annotation = annotation; } continue; } if (level <= 2) { if (reader.LocalName == "all") { level = 3; XmlSchemaAll all = XmlSchemaAll.Read(reader, h); if (all != null) { group.Particle = all; } continue; } if (reader.LocalName == "choice") { level = 3; XmlSchemaChoice choice = XmlSchemaChoice.Read(reader, h); if (choice != null) { group.Particle = choice; } continue; } if (reader.LocalName == "sequence") { level = 3; XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader, h); if (sequence != null) { group.Particle = sequence; } continue; } } reader.RaiseInvalidElementError(); } return(group); }
//<extension // base = QName // id = ID // {any attributes with non-schema namespace . . .}> // Content: (annotation?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))) //</extension> internal static XmlSchemaComplexContentExtension Read(XmlSchemaReader reader, ValidationEventHandler h) { XmlSchemaComplexContentExtension extension = new XmlSchemaComplexContentExtension(); reader.MoveToElement(); if (reader.NamespaceURI != XmlSchema.Namespace || reader.LocalName != xmlname) { error(h, "Should not happen :1: XmlSchemaComplexContentExtension.Read, name=" + reader.Name, null); reader.Skip(); return(null); } extension.LineNumber = reader.LineNumber; extension.LinePosition = reader.LinePosition; extension.SourceUri = reader.BaseURI; while (reader.MoveToNextAttribute()) { if (reader.Name == "base") { Exception innerex; extension.baseTypeName = XmlSchemaUtil.ReadQNameAttribute(reader, out innerex); if (innerex != null) { error(h, reader.Value + " is not a valid value for base attribute", innerex); } } else if (reader.Name == "id") { extension.Id = reader.Value; } else if ((reader.NamespaceURI == "" && reader.Name != "xmlns") || reader.NamespaceURI == XmlSchema.Namespace) { error(h, reader.Name + " is not a valid attribute for extension", null); } else { XmlSchemaUtil.ReadUnhandledAttribute(reader, extension); } } reader.MoveToElement(); if (reader.IsEmptyElement) { return(extension); } //Content: 1. annotation?, // (2.(group | all | choice | sequence)?, (3.(attribute | attributeGroup)*, 4.anyAttribute?))) int level = 1; while (reader.ReadNextElement()) { if (reader.NodeType == XmlNodeType.EndElement) { if (reader.LocalName != xmlname) { error(h, "Should not happen :2: XmlSchemaComplexContentExtension.Read, name=" + reader.Name, null); } break; } if (level <= 1 && reader.LocalName == "annotation") { level = 2; //Only one annotation XmlSchemaAnnotation annotation = XmlSchemaAnnotation.Read(reader, h); if (annotation != null) { extension.Annotation = annotation; } continue; } if (level <= 2) { if (reader.LocalName == "group") { level = 3; XmlSchemaGroupRef group = XmlSchemaGroupRef.Read(reader, h); if (group != null) { extension.particle = group; } continue; } if (reader.LocalName == "all") { level = 3; XmlSchemaAll all = XmlSchemaAll.Read(reader, h); if (all != null) { extension.particle = all; } continue; } if (reader.LocalName == "choice") { level = 3; XmlSchemaChoice choice = XmlSchemaChoice.Read(reader, h); if (choice != null) { extension.particle = choice; } continue; } if (reader.LocalName == "sequence") { level = 3; XmlSchemaSequence sequence = XmlSchemaSequence.Read(reader, h); if (sequence != null) { extension.particle = sequence; } continue; } } if (level <= 3) { if (reader.LocalName == "attribute") { level = 3; XmlSchemaAttribute attr = XmlSchemaAttribute.Read(reader, h); if (attr != null) { extension.Attributes.Add(attr); } continue; } if (reader.LocalName == "attributeGroup") { level = 3; XmlSchemaAttributeGroupRef attr = XmlSchemaAttributeGroupRef.Read(reader, h); if (attr != null) { extension.attributes.Add(attr); } continue; } } if (level <= 4 && reader.LocalName == "anyAttribute") { level = 5; XmlSchemaAnyAttribute anyattr = XmlSchemaAnyAttribute.Read(reader, h); if (anyattr != null) { extension.AnyAttribute = anyattr; } continue; } reader.RaiseInvalidElementError(); } return(extension); }
internal override bool ValidateDerivationByRestriction(XmlSchemaParticle baseParticle, ValidationEventHandler h, XmlSchema schema, bool raiseError) { if (this == baseParticle) // quick check { return(true); } XmlSchemaElement el = baseParticle as XmlSchemaElement; if (el != null) { // Forbidden if (raiseError) { error(h, "Invalid sequence paricle derivation."); } return(false); } XmlSchemaSequence seq = baseParticle as XmlSchemaSequence; if (seq != null) { // Recurse if (!ValidateOccurenceRangeOK(seq, h, schema, raiseError)) { return(false); } // If it is totally optional, then ignore their contents. if (seq.ValidatedMinOccurs == 0 && seq.ValidatedMaxOccurs == 0 && this.ValidatedMinOccurs == 0 && this.ValidatedMaxOccurs == 0) { return(true); } return(ValidateRecurse(seq, h, schema, raiseError)); } XmlSchemaAll all = baseParticle as XmlSchemaAll; if (all != null) { // RecurseUnordered XmlSchemaObjectCollection already = new XmlSchemaObjectCollection(); for (int i = 0; i < this.Items.Count; i++) { XmlSchemaElement de = this.Items [i] as XmlSchemaElement; if (de == null) { if (raiseError) { error(h, "Invalid sequence particle derivation by restriction from all."); } return(false); } foreach (XmlSchemaElement e in all.Items) { if (e.QualifiedName == de.QualifiedName) { if (already.Contains(e)) { if (raiseError) { error(h, "Base element particle is mapped to the derived element particle in a sequence two or more times."); } return(false); } else { already.Add(e); if (!de.ValidateDerivationByRestriction(e, h, schema, raiseError)) { return(false); } } } } } foreach (XmlSchemaElement e in all.Items) { if (!already.Contains(e)) { if (!e.ValidateIsEmptiable()) { if (raiseError) { error(h, "In base -all- particle, mapping-skipped base element which is not emptiable was found."); } return(false); } } } return(true); } XmlSchemaAny any = baseParticle as XmlSchemaAny; if (any != null) { // NSRecurseCheckCardinality return(ValidateNSRecurseCheckCardinality(any, h, schema, raiseError)); } XmlSchemaChoice choice = baseParticle as XmlSchemaChoice; if (choice != null) { // MapAndSum // In fact it is not Recurse, but it looks almost common. return(ValidateSeqRecurseMapSumCommon(choice, h, schema, false, true, raiseError)); } return(true); }