Example #1
0
        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);
                    }
                }
            }
        }
Example #2
0
        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;
        }
Example #4
0
        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);
        }
Example #5
0
        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);
                        }
                    }
                }
            }
        }