private void WalkParticle(XmlSchemaParticle particle, DomNodeType nodeType) { XmlSchemaElement element = particle as XmlSchemaElement; if (element != null) { XmlSchemaSimpleType simpleType = element.ElementSchemaType as XmlSchemaSimpleType; if (simpleType != null && element.MaxOccurs == 1) { XmlAttributeType attributeType = GetAttributeType(simpleType); string fieldName = GetFieldName(element.QualifiedName); XmlAttributeInfo attributeInfo = new XmlAttributeInfo(fieldName, attributeType); nodeType.Define(attributeInfo); m_annotations.Add(attributeInfo, GetAnnotation(element)); attributeInfo.IsElement = true; if (element.DefaultValue != null) { if (element.FixedValue != null) { throw new InvalidOperationException(string.Format("Schema element {0} cannot have both a default value and a fixed value", element.QualifiedName)); } attributeInfo.DefaultValue = attributeType.Convert(element.DefaultValue); } else if (element.FixedValue != null) { attributeInfo.DefaultValue = attributeType.Convert(element.FixedValue); } } else { DomNodeType childNodeType = null; if (simpleType != null) { bool firstTime; childNodeType = WrapSimpleType(simpleType, out firstTime); // The collada.xsd's ListOfUInts element breaks the generated Schema.cs file otherwise. if (firstTime) { // Add the value attribute XmlAttributeType valueAttributeType = GetAttributeType(simpleType); var valueAttributeInfo = new XmlAttributeInfo(string.Empty, valueAttributeType); childNodeType.Define(valueAttributeInfo); } } else { XmlSchemaComplexType complexType = element.ElementSchemaType as XmlSchemaComplexType; if (complexType != null) { childNodeType = GetNodeType(complexType, element); } } if (childNodeType != null) { int minOccurs = (int)Math.Min(element.MinOccurs, Int32.MaxValue); int maxOccurs = (int)Math.Min(element.MaxOccurs, Int32.MaxValue); if (particle.Parent is XmlSchemaChoice) { var parent = (XmlSchemaChoice)particle.Parent; if (parent.MinOccurs != 1) { minOccurs = (int)Math.Min(Math.Max(element.MinOccurs, parent.MinOccurs), Int32.MaxValue); } if (parent.MaxOccurs != 1) { maxOccurs = (int)Math.Min(Math.Max(element.MaxOccurs, parent.MaxOccurs), Int32.MaxValue); } } else if (particle.Parent is XmlSchemaSequence) { var parent = (XmlSchemaSequence)particle.Parent; if (parent.MinOccurs != 1) { minOccurs = (int)Math.Min(Math.Max(element.MinOccurs, parent.MinOccurs), Int32.MaxValue); } if (parent.MaxOccurs != 1) { maxOccurs = (int)Math.Min(Math.Max(element.MaxOccurs, parent.MaxOccurs), Int32.MaxValue); } } ChildInfo childInfo = new ChildInfo(GetFieldName(element.QualifiedName), childNodeType, maxOccurs > 1); if ((minOccurs > 0 || maxOccurs < Int32.MaxValue) && minOccurs <= maxOccurs) { childInfo.AddRule(new ChildCountRule(minOccurs, maxOccurs)); } // Check for substitution groups if (!element.RefName.IsEmpty) { m_refElements.Add(childInfo, element.RefName); } nodeType.Define(childInfo); m_annotations.Add(childInfo, GetAnnotation(element)); } } } else { XmlSchemaGroupBase grp = particle as XmlSchemaSequence; if (grp == null) { grp = particle as XmlSchemaChoice; } if (grp == null) { grp = particle as XmlSchemaAll; } if (grp != null) { foreach (XmlSchemaParticle subParticle in grp.Items) { WalkParticle(subParticle, nodeType); } } } }
private DomNodeType GetNodeType(XmlSchemaComplexType complexType, XmlSchemaElement element) { // get type name XmlQualifiedName name = complexType.QualifiedName; if (name.IsEmpty) // local type { name = GetLocalTypeName(element); } string typeName = name.ToString(); DomNodeType nodeType; if (!m_nodeTypes.TryGetValue(typeName, out nodeType)) { // build a new complex type and add it to the dictionary nodeType = new DomNodeType(typeName); m_nodeTypes.Add(typeName, nodeType); m_annotations.Add(nodeType, GetAnnotation(complexType)); DomNodeType baseType = null; XmlAttributeType valueType = null; XmlSchemaComplexType complexBaseType = GetBaseType(complexType); if (complexBaseType != null) { baseType = GetNodeType(complexBaseType, null); } XmlSchemaSimpleType simpleBase = complexType.BaseXmlSchemaType as XmlSchemaSimpleType; if (simpleBase != null) { valueType = GetAttributeType(simpleBase); } else if (complexType.IsMixed) { valueType = s_mixedTextFieldSimpleType; } WalkParticle(complexType.ContentTypeParticle, nodeType); if (valueType != null) { XmlAttributeInfo attributeInfo = new XmlAttributeInfo(string.Empty, valueType); nodeType.Define(attributeInfo); } // get XML attributes System.Collections.ICollection attributeUses = complexType.AttributeUses.Values; foreach (XmlSchemaAttribute attribute in attributeUses) { XmlAttributeType attributeType = GetAttributeType(attribute.AttributeSchemaType); string fieldName = GetFieldName(attribute.QualifiedName); XmlAttributeInfo attributeInfo = new XmlAttributeInfo(fieldName, attributeType); if (attribute.DefaultValue != null) { attributeInfo.DefaultValue = attributeType.Convert(attribute.DefaultValue); } m_annotations.Add(attributeInfo, GetAnnotation(attribute)); nodeType.Define(attributeInfo); } if (baseType != null) { nodeType.BaseType = baseType; } nodeType.IsAbstract = complexType.IsAbstract; } return(nodeType); }
private XmlAttributeType GetAttributeType(XmlSchemaSimpleType simpleType) { XmlAttributeType attributeType; if (!m_attributeTypes.TryGetValue(simpleType.QualifiedName.ToString(), out attributeType)) { bool simpleList = simpleType.Content is XmlSchemaSimpleTypeList; int length = 1; if (simpleList) length = Int32.MaxValue; // unbounded, until restricted List<AttributeRule> rules = null; XmlSchemaSimpleTypeRestriction restriction = simpleType.Content as XmlSchemaSimpleTypeRestriction; if (restriction != null) { if (restriction.BaseTypeName != null) { XmlAttributeType baseType; m_attributeTypes.TryGetValue(restriction.BaseTypeName.ToString(), out baseType); if (baseType != null) length = baseType.Length; } foreach (XmlSchemaFacet facet in restriction.Facets) { XmlSchemaLengthFacet lengthFacet = facet as XmlSchemaLengthFacet; if (lengthFacet != null) { Int32.TryParse(lengthFacet.Value, out length); continue; } // also handle minLength, maxLength facets in a limited fashion, ie. either one // will specify the array length XmlSchemaMinLengthFacet minLengthFacet = facet as XmlSchemaMinLengthFacet; if (minLengthFacet != null) { int minLength; if (Int32.TryParse(minLengthFacet.Value, out minLength)) length = Math.Max(length, minLength); continue; } XmlSchemaMaxLengthFacet maxLengthFacet = facet as XmlSchemaMaxLengthFacet; if (maxLengthFacet != null) { int maxLength; if (Int32.TryParse(maxLengthFacet.Value, out maxLength)) length = Math.Max(length, maxLength); continue; } } rules = GetRules(restriction); } string typeName = simpleType.QualifiedName.ToString(); // if xs:IDREF, then the attribute type should be DomNode as this is a reference Type valueType = simpleType.Datatype.ValueType; XmlTypeCode xmlTypeCode = simpleType.Datatype.TypeCode; if (xmlTypeCode == XmlTypeCode.Idref) { if (valueType.IsArray) valueType = typeof(string[]); else valueType = typeof(DomNode); } // map xs:integer to xs:int (ATGI schema uses xs:integer, which we don't want to map to System.Decimal) if (xmlTypeCode == XmlTypeCode.Integer) { if (valueType.IsArray) valueType = typeof(Int32[]); else valueType = typeof(Int32); xmlTypeCode = XmlTypeCode.Int; } else if (xmlTypeCode == XmlTypeCode.NonNegativeInteger) { if (valueType.IsArray) valueType = typeof(UInt32[]); else valueType = typeof(UInt32); xmlTypeCode = XmlTypeCode.UnsignedInt; } // create our extended attribute type attributeType = new XmlAttributeType(typeName, valueType, length, xmlTypeCode); m_annotations.Add(attributeType, GetAnnotation(simpleType)); if (rules != null) { foreach (AttributeRule rule in rules) attributeType.AddRule(rule); } if (!string.IsNullOrEmpty(typeName)) m_attributeTypes.Add(typeName, attributeType); } return attributeType; }
private XmlAttributeType GetAttributeType(XmlSchemaSimpleType simpleType) { XmlAttributeType attributeType; if (!m_attributeTypes.TryGetValue(simpleType.QualifiedName.ToString(), out attributeType)) { bool simpleList = simpleType.Content is XmlSchemaSimpleTypeList; int length = 1; if (simpleList) { length = Int32.MaxValue; // unbounded, until restricted } List <AttributeRule> rules = null; XmlSchemaSimpleTypeRestriction restriction = simpleType.Content as XmlSchemaSimpleTypeRestriction; if (restriction != null) { if (restriction.BaseTypeName != null) { XmlAttributeType baseType; m_attributeTypes.TryGetValue(restriction.BaseTypeName.ToString(), out baseType); if (baseType != null) { length = baseType.Length; } } foreach (XmlSchemaFacet facet in restriction.Facets) { XmlSchemaLengthFacet lengthFacet = facet as XmlSchemaLengthFacet; if (lengthFacet != null) { Int32.TryParse(lengthFacet.Value, out length); continue; } // also handle minLength, maxLength facets in a limited fashion, ie. either one // will specify the array length XmlSchemaMinLengthFacet minLengthFacet = facet as XmlSchemaMinLengthFacet; if (minLengthFacet != null) { int minLength; if (Int32.TryParse(minLengthFacet.Value, out minLength)) { length = Math.Max(length, minLength); } continue; } XmlSchemaMaxLengthFacet maxLengthFacet = facet as XmlSchemaMaxLengthFacet; if (maxLengthFacet != null) { int maxLength; if (Int32.TryParse(maxLengthFacet.Value, out maxLength)) { length = Math.Max(length, maxLength); } continue; } } rules = GetRules(restriction); } string typeName = simpleType.QualifiedName.ToString(); // if xs:IDREF, then the attribute type should be DomNode as this is a reference Type valueType = simpleType.Datatype.ValueType; XmlTypeCode xmlTypeCode = simpleType.Datatype.TypeCode; if (xmlTypeCode == XmlTypeCode.Idref) { if (valueType.IsArray) { valueType = typeof(string[]); } else { valueType = typeof(DomNode); } } // map xs:integer to xs:int (ATGI schema uses xs:integer, which we don't want to map to System.Decimal) if (xmlTypeCode == XmlTypeCode.Integer) { if (valueType.IsArray) { valueType = typeof(Int32[]); } else { valueType = typeof(Int32); } xmlTypeCode = XmlTypeCode.Int; } else if (xmlTypeCode == XmlTypeCode.NonNegativeInteger) { if (valueType.IsArray) { valueType = typeof(UInt32[]); } else { valueType = typeof(UInt32); } xmlTypeCode = XmlTypeCode.UnsignedInt; } // create our extended attribute type attributeType = new XmlAttributeType(typeName, valueType, length, xmlTypeCode); m_annotations.Add(attributeType, GetAnnotation(simpleType)); if (rules != null) { foreach (AttributeRule rule in rules) { attributeType.AddRule(rule); } } if (!string.IsNullOrEmpty(typeName)) { m_attributeTypes.Add(typeName, attributeType); } } return(attributeType); }
private void WalkParticle(XmlSchemaParticle particle, DomNodeType nodeType) { XmlSchemaElement element = particle as XmlSchemaElement; if (element != null) { XmlSchemaSimpleType simpleType = element.ElementSchemaType as XmlSchemaSimpleType; if (simpleType != null && element.MaxOccurs == 1) { XmlAttributeType attributeType = GetAttributeType(simpleType); string fieldName = GetFieldName(element.QualifiedName); XmlAttributeInfo attributeInfo = new XmlAttributeInfo(fieldName, attributeType); nodeType.Define(attributeInfo); m_annotations.Add(attributeInfo, GetAnnotation(element)); attributeInfo.IsElement = true; if (element.DefaultValue != null) { if (element.FixedValue != null) { throw new InvalidOperationException(string.Format("Schema element {0} cannot have both a default value and a fixed value", element.QualifiedName)); } attributeInfo.DefaultValue = attributeType.Convert(element.DefaultValue); } else if (element.FixedValue != null) { attributeInfo.DefaultValue = attributeType.Convert(element.FixedValue); } } else { DomNodeType childNodeType = null; if (simpleType != null) { childNodeType = WrapSimpleType(simpleType); // Add the value attribute XmlAttributeType valueAttributeType = GetAttributeType(simpleType); var valueAttributeInfo = new XmlAttributeInfo(string.Empty, valueAttributeType); childNodeType.Define(valueAttributeInfo); } else { XmlSchemaComplexType complexType = element.ElementSchemaType as XmlSchemaComplexType; if (complexType != null) { childNodeType = GetNodeType(complexType, element); } } if (childNodeType != null) { int minOccurs = (int)Math.Min(element.MinOccurs, Int32.MaxValue); int maxOccurs = (int)Math.Min(element.MaxOccurs, Int32.MaxValue); // If <xs:choice> is within a <xs:sequence>, choose the most relaxed constraints. if (particle.Parent is XmlSchemaChoice && particle.Parent.Parent is XmlSchemaSequence) { XmlSchemaChoice parent = (XmlSchemaChoice)particle.Parent; int parentMinOccurs = (int)Math.Min(parent.MinOccurs, Int32.MaxValue); int parentMaxOccurs = (int)Math.Min(parent.MaxOccurs, Int32.MaxValue); minOccurs = Math.Min(parentMinOccurs, minOccurs); maxOccurs = Math.Max(parentMaxOccurs, maxOccurs); } ChildInfo childInfo = new ChildInfo(GetFieldName(element.QualifiedName), childNodeType, maxOccurs > 1); if (minOccurs > 0 || maxOccurs < Int32.MaxValue) { childInfo.AddRule(new ChildCountRule(minOccurs, maxOccurs)); } // Check for substitution groups if (!element.RefName.IsEmpty) { m_refElements.Add(childInfo, element.RefName); } nodeType.Define(childInfo); m_annotations.Add(childInfo, GetAnnotation(element)); } } } else { // if sequence, continue collecting elements XmlSchemaSequence sequence = particle as XmlSchemaSequence; if (sequence != null) { foreach (XmlSchemaParticle subParticle in sequence.Items) { WalkParticle(subParticle, nodeType); } } else { XmlSchemaChoice choice = particle as XmlSchemaChoice; if (choice != null) { // for now, treat choice as if it were a sequence foreach (XmlSchemaParticle subParticle in choice.Items) { WalkParticle(subParticle, nodeType); } } } } }