Export (0) Print
Expand All

Editing XML Schemas

Editing an XML schema is one of the most important features of the Schema Object Model (SOM). All of the pre-schema-compilation properties of the SOM can be used to change the existing values in an XML schema. The XML schema can then be recompiled to reflect the changes.

The first step in editing a schema loaded into the SOM is to traverse the schema. You should be familiar with traversing a schema using the SOM API before you attempt to edit a schema. You should also be familiar with the pre- and post-schema-compilation properties of the Post-Schema-Compilation-Infoset (PSCI).

In this section, two code examples are provided, both of which edit the customer schema created in the Building XML Schemas topic. The first code example adds a new PhoneNumber element to the Customer element and the second code example adds a new Title attribute to the FirstName element. The first sample also uses the post-schema-compilation XmlSchema.Elements collection as the means of traversing the customer schema while the second code example uses the pre-schema-compilation XmlSchema.Items collection.

This first code example adds a new PhoneNumber element to the Customer element of the customer schema. The code example edits the customer schema in the following steps.

  1. Adds the customer schema to a new XmlSchemaSet object and then compiles it. Any schema validation warnings and errors encountered reading or compiling the schema are handled by the ValidationEventHandler delegate.

  2. Retrieves the compiled XmlSchema object from the XmlSchemaSet by iterating over the Schemas property. Because the schema is compiled, Post-Schema-Compilation-Infoset (PSCI) properties are accessible.

  3. Creates the PhoneNumber element using the XmlSchemaElement class, the xs:string simple type restriction using the XmlSchemaSimpleType and XmlSchemaSimpleTypeRestriction classes, adds a pattern facet to the Facets property of the restriction, and adds the restriction to the Content property of the simple type and the simple type to the SchemaType of the PhoneNumber element.

  4. Iterates over each XmlSchemaElement in the Values collection of the post-schema-compilation XmlSchema.Elements collection.

  5. If the QualifiedName of the element is "Customer", gets the complex type of the Customer element using the XmlSchemaComplexType class and the sequence particle of the complex type using the XmlSchemaSequence class.

  6. Adds the new PhoneNumber element to the sequence containing the existing FirstName and LastName elements using the pre-schema-compilation Items collection of the sequence.

  7. Finally, reprocesses and compiles the modified XmlSchema object using the Reprocess and Compile methods of the XmlSchemaSet class and writes it to the console.

The following is the complete code example.

using System;
using System.Xml;
using System.Xml.Schema;

class XmlSchemaEditExample
{
    static void Main(string[] args)
    {
        // Add the customer schema to a new XmlSchemaSet and compile it. 
        // Any schema validation warnings and errors encountered reading or  
        // compiling the schema are handled by the ValidationEventHandler delegate.
        XmlSchemaSet schemaSet = new XmlSchemaSet();
        schemaSet.ValidationEventHandler += new ValidationEventHandler(ValidationCallback);
        schemaSet.Add("http://www.tempuri.org", "customer.xsd");
        schemaSet.Compile();

        // Retrieve the compiled XmlSchema object from the XmlSchemaSet 
        // by iterating over the Schemas property.
        XmlSchema customerSchema = null;
        foreach (XmlSchema schema in schemaSet.Schemas())
        {
            customerSchema = schema;
        }

        // Create the PhoneNumber element.
        XmlSchemaElement phoneElement = new XmlSchemaElement();
        phoneElement.Name = "PhoneNumber";

        // Create the xs:string simple type restriction.
        XmlSchemaSimpleType phoneType = new XmlSchemaSimpleType();
        XmlSchemaSimpleTypeRestriction restriction =
            new XmlSchemaSimpleTypeRestriction();
        restriction.BaseTypeName = new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema");

        // Add a pattern facet to the restriction.
        XmlSchemaPatternFacet phonePattern = new XmlSchemaPatternFacet();
        phonePattern.Value = "\\d{3}-\\d{3}-\\d(4)";
        restriction.Facets.Add(phonePattern);

        // Add the restriction to the Content property of the simple type 
        // and the simple type to the SchemaType of the PhoneNumber element.
        phoneType.Content = restriction;
        phoneElement.SchemaType = phoneType;

        // Iterate over each XmlSchemaElement in the Values collection 
        // of the Elements property. 
        foreach (XmlSchemaElement element in customerSchema.Elements.Values)
        {
            // If the qualified name of the element is "Customer", 
            // get the complex type of the Customer element   
            // and the sequence particle of the complex type. 
            if (element.QualifiedName.Name.Equals("Customer"))
            {
                XmlSchemaComplexType customerType =
                    element.ElementSchemaType as XmlSchemaComplexType;
                XmlSchemaSequence sequence =
                    customerType.Particle as XmlSchemaSequence;

                // Add the new PhoneNumber element to the sequence.
                sequence.Items.Add(phoneElement);
            }
        }

        // Reprocess and compile the modified XmlSchema object and write it to the console.
        schemaSet.Reprocess(customerSchema);
        schemaSet.Compile();
        customerSchema.Write(Console.Out);
    }

    static void ValidationCallback(object sender, ValidationEventArgs args)
    {
        if (args.Severity == XmlSeverityType.Warning)
            Console.Write("WARNING: ");
        else if (args.Severity == XmlSeverityType.Error)
            Console.Write("ERROR: ");

        Console.WriteLine(args.Message);
    }
}

The following is the modified customer schema created in the Building XML Schemas topic.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://www.tempuri.org" targetNamespace="http://www.tempuri.org" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Customer">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="FirstName" type="xs:string" />
        <xs:element name="LastName" type="tns:LastNameType" />
        <xs:element name="PhoneNumber"> 
          <xs:simpleType> 
            <xs:restriction base="xs:string"> 
              <xs:pattern value="\d{3}-\d{3}-\d(4)" /> 
            </xs:restriction> 
          </xs:simpleType> 
        </xs:element>
      </xs:sequence>
      <xs:attribute name="CustomerId" type="xs:positiveInteger" use="required" /
>
    </xs:complexType>
  </xs:element>
  <xs:simpleType name="LastNameType">
    <xs:restriction base="xs:string">
      <xs:maxLength value="20" />
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

This second code example, adds a new Title attribute to the FirstName element of the customer schema. In the first code example, the type of the FirstName element is xs:string. For the FirstName element to have an attribute along with string content, its type must be changed to a complex type with a simple content extension content model.

The code example edits the customer schema in the following steps.

  1. Adds the customer schema to a new XmlSchemaSet object and then compiles it. Any schema validation warnings and errors encountered reading or compiling the schema are handled by the ValidationEventHandler delegate.

  2. Retrieves the compiled XmlSchema object from the XmlSchemaSet by iterating over the Schemas property. Because the schema is compiled, Post-Schema-Compilation-Infoset (PSCI) properties are accessible.

  3. Creates a new complex type for the FirstName element using the XmlSchemaComplexType class.

  4. Creates a new simple content extension, with a base type of xs:string, using the XmlSchemaSimpleContent and XmlSchemaSimpleContentExtension classes.

  5. Creates the new Title attribute using the XmlSchemaAttribute class, with a SchemaTypeName of xs:string and adds the attribute to the simple content extension.

  6. Sets the content model of the simple content to the simple content extension and the content model of the complex type to the simple content.

  7. Adds the new complex type to the pre-schema-compilation XmlSchema.Items collection.

  8. Iterates over each XmlSchemaObject in the pre-schema-compilation XmlSchema.Items collection.

Note Note

Because the FirstName element is not a global element in the schema, it is not available in the XmlSchema.Items or XmlSchema.Elements collections. The code example locates the FirstName element by first locating the Customer element.

The first code example traversed the schema using the post-schema-compilation XmlSchema.Elements collection. In this sample, the pre-schema-compilation XmlSchema.Items collection is used to traverse the schema. While both collections provide access to the global elements in the schema, iterating through the Items collection is more time consuming because you must iterate over all global elements in the schema and it does not have any PSCI properties. The PSCI collections (XmlSchema.Elements, XmlSchema.Attributes, XmlSchema.SchemaTypes, and so on) provide direct access to their global elements, attributes, and types and their PSCI properties.

  1. If the XmlSchemaObject is an element, whose QualifiedName is "Customer", gets the complex type of the Customer element using the XmlSchemaComplexType class and the sequence particle of the complex type using the XmlSchemaSequence class.

  2. Iterates over each XmlSchemaParticle in the pre-schema-compilation XmlSchemaSequence.Items collection.

  3. If the XmlSchemaParticle is an element, who's QualifiedName is "FirstName", sets the SchemaTypeName of the FirstName element to the new FirstName complex type.

  4. Finally, reprocesses and compiles the modified XmlSchema object using the Reprocess and Compile methods of the XmlSchemaSet class and writes it to the console.

The following is the complete code example.

using System;
using System.Xml;
using System.Xml.Schema;

class XmlSchemaEditExample
{
    static void Main(string[] args)
    {
        // Add the customer schema to a new XmlSchemaSet and compile it. 
        // Any schema validation warnings and errors encountered reading or  
        // compiling the schema are handled by the ValidationEventHandler delegate.
        XmlSchemaSet schemaSet = new XmlSchemaSet();
        schemaSet.ValidationEventHandler += new ValidationEventHandler(ValidationCallback);
        schemaSet.Add("http://www.tempuri.org", "customer.xsd");
        schemaSet.Compile();

        // Retrieve the compiled XmlSchema object from the XmlSchemaSet 
        // by iterating over the Schemas property.
        XmlSchema customerSchema = null;
        foreach (XmlSchema schema in schemaSet.Schemas())
        {
            customerSchema = schema;
        }

        // Create a complex type for the FirstName element.
        XmlSchemaComplexType complexType = new XmlSchemaComplexType();
        complexType.Name = "FirstNameComplexType";

        // Create a simple content extension with a base type of xs:string.
        XmlSchemaSimpleContent simpleContent = new XmlSchemaSimpleContent();
        XmlSchemaSimpleContentExtension simpleContentExtension =
            new XmlSchemaSimpleContentExtension();
        simpleContentExtension.BaseTypeName =
            new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema");

        // Create the new Title attribute with a SchemaTypeName of xs:string 
        // and add it to the simple content extension.
        XmlSchemaAttribute attribute = new XmlSchemaAttribute();
        attribute.Name = "Title";
        attribute.SchemaTypeName =
            new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema");
        simpleContentExtension.Attributes.Add(attribute);

        // Set the content model of the simple content to the simple content extension 
        // and the content model of the complex type to the simple content.
        simpleContent.Content = simpleContentExtension;
        complexType.ContentModel = simpleContent;

        // Add the new complex type to the pre-schema-compilation Items collection.
        customerSchema.Items.Add(complexType);

        // Iterate over each XmlSchemaObject in the pre-schema-compilation 
        // Items collection. 
        foreach (XmlSchemaObject schemaObject in customerSchema.Items)
        {
            // If the XmlSchemaObject is an element, whose QualifiedName 
            // is "Customer", get the complex type of the Customer element
            // and the sequence particle of the complex type. 
            if (schemaObject is XmlSchemaElement)
            {
                XmlSchemaElement element = schemaObject as XmlSchemaElement;

                if (element.QualifiedName.Name.Equals("Customer"))
                {
                    XmlSchemaComplexType customerType =
                        element.ElementSchemaType as XmlSchemaComplexType;

                    XmlSchemaSequence sequence =
                        customerType.Particle as XmlSchemaSequence;

                    // Iterate over each XmlSchemaParticle in the pre-schema-compilation 
                    // Items property. 
                    foreach (XmlSchemaParticle particle in sequence.Items)
                    {
                        // If the XmlSchemaParticle is an element, who's QualifiedName 
                        // is "FirstName", set the SchemaTypeName of the FirstName element
                        // to the new FirstName complex type. 
                        if (particle is XmlSchemaElement)
                        {
                            XmlSchemaElement childElement =
                                particle as XmlSchemaElement;

                            if (childElement.Name.Equals("FirstName"))
                            {
                                childElement.SchemaTypeName =
                                    new XmlQualifiedName("FirstNameComplexType",
                                    "http://www.tempuri.org");
                            }
                        }
                    }
                }
            }
        }

        // Reprocess and compile the modified XmlSchema object and write it to the console.
        schemaSet.Reprocess(customerSchema);
        schemaSet.Compile();
        customerSchema.Write(Console.Out);
    }

    static void ValidationCallback(object sender, ValidationEventArgs args)
    {
        if (args.Severity == XmlSeverityType.Warning)
            Console.Write("WARNING: ");
        else if (args.Severity == XmlSeverityType.Error)
            Console.Write("ERROR: ");

        Console.WriteLine(args.Message);
    }
}

The following is the modified customer schema created in the Building XML Schemas topic.

<?xml version="1.0" encoding=" utf-8"?>
<xs:schema xmlns:tns="http://www.tempuri.org" targetNamespace="http://www.tempuri.org" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Customer">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="FirstName" type="tns:FirstNameComplexType" />
        <xs:element name="LastName" type="tns:LastNameType" />
      </xs:sequence>
      <xs:attribute name="CustomerId" type="xs:positiveInteger" use="required" /
>
    </xs:complexType>
  </xs:element>
  <xs:simpleType name="LastNameType">
    <xs:restriction base="xs:string">
      <xs:maxLength value="20" />
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="FirstNameComplexType"> 
    <xs:simpleContent> 
      <xs:extension base="xs:string"> 
        <xs:attribute name="Title" type="xs:string" /> 
      </xs:extension> 
    </xs:simpleContent> 
  </xs:complexType>
</xs:schema>
Show:
© 2015 Microsoft