Search code examples
c#xmlxsdschema

Problems adding Any-Element to dynamically created XSD-Schema


I just wanna add an Any-element node to an existing XSD-Schema created by this code particle:

    private void CreateSchema()
    {
        //This function returns the XML Schema definition of a XML Element by using the Generation function of a Dataset

        XmlSchemaInference x_scheme = new XmlSchemaInference();
        this.XsDSchemaSet = x_scheme.InferSchema(this.myXmlElement.CreateReader());

        this.XsDSchemaSet.Compile();;
    } 

After I created the XSD-Schemaset some parts have to be modified. The following code sets the Min- and max-Occurs attributes of existing elements which also works fine. After modification of the attributes I also have to add an Element of type XmlSchemaElement to the Items-collection of the XmlSchemaSequence like you see in the few lines above the end of the sample code. That does not work. While debugging i can see the element within the Items-collection, but after Reprocessing & recompilation of the Schemaset the modified attributes are set pretty well, but the generated Any-element is not present like you see in the MessageBox of final result. Could anybody help?

  private bool ModifyXsdElement(XmlSchemaElement element, XElement myXmlElement)
    {
        // this function modifies the occurance min an max of the child elements

        XmlSchemaSimpleType simpleType = element.ElementSchemaType as XmlSchemaSimpleType;
        if (simpleType != null)
        {
            MessageBox.Show("Function XsdModifyElement: Error - Simple Type!");
            return false;
        }
        else
        {
            XmlSchemaComplexType complexType = element.ElementSchemaType as XmlSchemaComplexType;
            if (complexType != null) //This is a complexType object
            {
                if (complexType.AttributeUses.Count > 0)
                {
                    //todo: anything if there are attributes
                }
                bool typeMatch = false;
                XmlSchemaSequence sequence = complexType.ContentTypeParticle as XmlSchemaSequence;
                if (sequence != null)
                {
                    typeMatch = true;
                    string fixedValue = string.Empty;
                    XmlSchemaElement el = new XmlSchemaElement();
                    foreach (XmlSchemaElement childElement in sequence.Items)
                    {
                        //MessageBox.Show("Child Element: " + childElement.Name);
                        int iOccCtr = GetNoOfXmlChildElements(childElement.Name, myXmlElement);
                        childElement.MinOccurs = iOccCtr;
                        childElement.MaxOccurs = iOccCtr;
                        childElement.MinOccursString = iOccCtr.ToString();
                        childElement.MaxOccursString = iOccCtr.ToString();
                        if (FixedValues.TryGetValue(childElement.Name.ToString(), out fixedValue))
                            childElement.FixedValue = fixedValue;
                        el = childElement;
                    }

                    //Add any element
                    XmlSchemaAny anyElement = new XmlSchemaAny();
                    anyElement.MinOccurs = 0;
                    anyElement.MaxOccurs = 1;
                    anyElement.ProcessContents = XmlSchemaContentProcessing.Lax;
                    anyElement.Parent = sequence;
                    sequence.Items.Add(anyElement);
                }
            }
        }
        return true;
    }

The final result of the compiled Schema looks like that:

<?xml version=\"1.0\"?>
<xs:schema attributeFormDefault=\"unqualified\" elementFormDefault=\"unqualified\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">
    <xs:element name=\"STEP\">
        <xs:complexType>
            <xs:sequence>    
                <xs:element minOccurs=\"1\" maxOccurs=\"1\" fixed=\"0002\" name=\"LFDNR\" type=\"xs:unsignedByte\" />      
                <xs:element minOccurs=\"1\" maxOccurs=\"1\" name=\"FUNKTIONSNUMMER\" />        
                <xs:element minOccurs=\"1\" maxOccurs=\"1\" fixed=\"Firmwareinformationen lesen\" name=\"FUNKTIONSNAME\" type=\"xs:string\" />    
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Thanks for your help! Br Matthias


Solution

  • Your problem is due to your use of a post compilation property. As the help has it:

    The particle for the content type. The post-compilation value of the ContentType particle.

    In general, one hint in using .NET's SOM API is to look for properties that have a setter as well. "hint" since some of the properties are both: post compilation, and user configurable.

    If your complex type's definition has an explicit content model (extension or restriction), then you need to use the XmlSchemaComplexType.ContentModel. If it's an XmlSchemaComplexContent, navigate its Content property (one of XmlSchemaComplexContentRestriction or XmlSchemaComplexContentExtension); each of these types have a Particle property, which is the one you can modify.

    Otherwise, if there's no content model, simply access the XmlSchemaComplexType.Particle.