How to parse an xsd file which has nested elements(complexType and simpleType elements and attributes)?

StackOverflow https://stackoverflow.com/questions/11969063

  •  26-06-2021
  •  | 
  •  

Question

I have an xsd file like that:

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="transfer">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="sourceGLN" type="xs:string" minOccurs="1" maxOccurs="1" />
                <xs:element name="destinationGLN" type="xs:string" minOccurs="1" maxOccurs="1" />
                <xs:element name="actionType" minOccurs="1" maxOccurs="1">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:enumeration value="P" /> <!-- Mal Alim (Purchase) -->
                            <xs:enumeration value="S" /> <!-- Satis (Sale) -->
                            <xs:enumeration value="C" /> <!-- Cancel Sale (Cancel) -->
                            <xs:enumeration value="R" /> <!-- Iade (Return) -->
                            <xs:enumeration value="D" /> <!-- Deaktivasyon (Deactivation) -->
                            <xs:enumeration value="M" /> <!-- Uretim (Manufacture) -->
                            <xs:enumeration value="I" /> <!-- Ithalat (Import) -->
                            <xs:enumeration value="X" /> <!-- Ihrac (eXport) -->
                            <xs:enumeration value="O" /> <!-- Sarf (cOnsume) -->
                            <xs:enumeration value="N" /> <!-- Bilgi (iNformation) -->
                            <xs:enumeration value="T" /> <!-- Devir (Transfer) -->
                            <xs:enumeration value="L" /> <!-- Devir Iptal (canceL Transfer) -->
                            <xs:enumeration value="F" /> <!-- Aktarim (non-its transFer) -->
                            <xs:enumeration value="K" /> <!-- Aktarim Iptal (non-its cancel transfer) -->
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
                <xs:element name="shipTo" type="xs:string" minOccurs="0" maxOccurs="1" />
                <xs:element name="documentNumber" type="xs:string" minOccurs="0" maxOccurs="1" />
                <xs:element name="documentDate" type="xs:date" minOccurs="0" maxOccurs="1" />
                <xs:element name="note" type="xs:string" minOccurs="0" maxOccurs="1" />
                <xs:element name="version" type="xs:string" minOccurs="0" maxOccurs="1" />
                <xs:element name="carrier" type="carrierType" minOccurs="1" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="carrierType">
        <xs:sequence minOccurs="1" maxOccurs="unbounded">
            <xs:choice minOccurs="1" maxOccurs="1">
                <xs:element name="productList" type="productListType" minOccurs="1" maxOccurs="1" />
                <xs:element name="carrier" type="carrierType" minOccurs="1" maxOccurs="1" />
            </xs:choice>
        </xs:sequence>
        <xs:attribute name="carrierLabel" use="required">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:length value="20" />
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="containerType" type="xs:string" use="optional" />
    </xs:complexType>
    <xs:complexType name="productListType">
        <xs:sequence>
            <xs:element name="serialNumber" type="xs:string" minOccurs="1" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="GTIN" type="xs:string" use="required" />
        <xs:attribute name="lotNumber" type="xs:string" use="required" />
        <xs:attribute name="productionDate" type="xs:date" use="optional" />
        <xs:attribute name="expirationDate" type="xs:date" use="required" />
        <xs:attribute name="PONumber" type="xs:string" use="optional" />
    </xs:complexType>
</xs:schema>

And I have code Like that:

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

namespace ConsoleApplication1
{
    class XmlSchemaTraverseExample
    {
        static void Main()
        {
            // 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.w3.org/2001/XMLSchema", "C:\\Users\\ahmet.ulusoy\\Desktop\\pts_xml_schema_v_1_4.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;
            }

            // Iterate over each XmlSchemaElement in the Values collection
            // of the Elements property.
            foreach (XmlSchemaElement element in customerSchema.Elements.Values)
            {

                Console.WriteLine("Element: {0}", element.Name);

                // Get the complex type of the Customer element.
                XmlSchemaComplexType complexType = element.ElementSchemaType as XmlSchemaComplexType;

                // If the complex type has any attributes, get an enumerator 
                // and write each attribute name to the console.
                if (complexType.AttributeUses.Count > 0)
                {
                    IDictionaryEnumerator enumerator =
                        complexType.AttributeUses.GetEnumerator();

                    while (enumerator.MoveNext())
                    {
                        XmlSchemaAttribute attribute =
                            (XmlSchemaAttribute)enumerator.Value;

                        Console.WriteLine("Attribute: {0}", attribute.Name);
                    }
                }

                // Get the sequence particle of the complex type.
                XmlSchemaSequence sequence = complexType.ContentTypeParticle as XmlSchemaSequence;

                // Iterate over each XmlSchemaElement in the Items collection.
                foreach (   XmlSchemaElement childElement in sequence.Items)
                {
                    Console.WriteLine("Element: {0}", childElement.Name);
                }
            }
        }

        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);
        }
    }
}

When I tried to run it gives me the just first element' elements name. After that how can I take other two xs:complexType name="carrierType" and xs:complexType name="productListType" and their sub elements and attributes?

I made this part and gonna update the code.

I also want to make a generic class with these data and data types. What do I should?

Thank you for your advance.

Was it helpful?

Solution

If you got a xsd document like above, you may need a code like that.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Schema;
using System.Collections;
using System.Data;

namespace ConsoleApplication1
{
    class Program
    {
        private static void Main(string[] args)
        {
            XmlSchemaSet schemaSet = new XmlSchemaSet();
            schemaSet.ValidationEventHandler += new ValidationEventHandler(ValidationCallback);
            schemaSet.Add("http://www.w3.org/2001/XMLSchema", "C:\\Users\\ahmet.ulusoy\\Desktop\\pts_xml_schema_v_1_4.xsd");
            schemaSet.Compile();

            XmlSchema xmlSchema = null;
            foreach (XmlSchema schema in schemaSet.Schemas())
            {
                xmlSchema = schema;
            }

            DataSet myDS = new DataSet();
            myDS.ReadXmlSchema("C:\\Users\\ahmet.ulusoy\\Desktop\\pts_xml_schema_v_1_4.xsd");

            foreach (object item in xmlSchema.Items)
            {
                XmlSchemaElement schemaElement = item as XmlSchemaElement;
                XmlSchemaComplexType complexType = item as XmlSchemaComplexType;

                if (schemaElement != null)
                {
                    Console.Out.WriteLine("Schema Element: {0}", schemaElement.Name);

                    XmlSchemaType schemaType = schemaElement.SchemaType;
                    XmlSchemaComplexType schemaComplexType = schemaType as XmlSchemaComplexType;

                    if (schemaComplexType != null)
                    {
                        XmlSchemaParticle particle = schemaComplexType.Particle;
                        XmlSchemaSequence sequence = particle as XmlSchemaSequence;

                        if (sequence != null)
                        {
                            foreach (XmlSchemaElement childElement in sequence.Items)
                            {
                                Console.Out.WriteLine("    Element/Type: {0}:{1}", childElement.Name,
                                                      childElement.SchemaTypeName.Name);
                            }

                        }
                        if (schemaComplexType.AttributeUses.Count > 0)
                        {
                            IDictionaryEnumerator enumerator = schemaComplexType.AttributeUses.GetEnumerator();

                            while (enumerator.MoveNext())
                            {
                                XmlSchemaAttribute attribute = (XmlSchemaAttribute)enumerator.Value;

                                Console.Out.WriteLine("      Attribute/Type: {0}", attribute.Name);
                            }
                        }
                    }
                }
                else if (complexType != null)
                {
                    Console.Out.WriteLine("Complex Type: {0}", complexType.Name);
                    OutputElements(complexType.Particle);
                    if (complexType.AttributeUses.Count > 0)
                    {
                        IDictionaryEnumerator enumerator = complexType.AttributeUses.GetEnumerator();

                        while (enumerator.MoveNext())
                        {
                            XmlSchemaAttribute attribute = (XmlSchemaAttribute)enumerator.Value;
                            Console.Out.WriteLine("      Attribute/Type: {0}", attribute.Name);
                        }
                    }
                }
                Console.Out.WriteLine();
            }

            Console.Out.WriteLine();
            Console.In.ReadLine();
        }

        private static void OutputElements(XmlSchemaParticle particle)
        {
            XmlSchemaSequence sequence = particle as XmlSchemaSequence;
            XmlSchemaChoice choice = particle as XmlSchemaChoice;
            XmlSchemaAll all = particle as XmlSchemaAll;

            if (sequence != null)
            {
                Console.Out.WriteLine("  Sequence");

                for (int i = 0; i < sequence.Items.Count; i++)
                {
                    XmlSchemaElement childElement = sequence.Items[i] as XmlSchemaElement;
                    XmlSchemaSequence innerSequence = sequence.Items[i] as XmlSchemaSequence;
                    XmlSchemaChoice innerChoice = sequence.Items[i] as XmlSchemaChoice;
                    XmlSchemaAll innerAll = sequence.Items[i] as XmlSchemaAll;

                    if (childElement != null)
                    {
                        Console.Out.WriteLine("    Element/Type: {0}:{1}", childElement.Name,
                                              childElement.SchemaTypeName.Name);
                    }
                    else OutputElements(sequence.Items[i] as XmlSchemaParticle);
                }
            }
            else if (choice != null)
            {
                Console.Out.WriteLine("  Choice");
                for (int i = 0; i < choice.Items.Count; i++)
                {
                    XmlSchemaElement childElement = choice.Items[i] as XmlSchemaElement;
                    XmlSchemaSequence innerSequence = choice.Items[i] as XmlSchemaSequence;
                    XmlSchemaChoice innerChoice = choice.Items[i] as XmlSchemaChoice;
                    XmlSchemaAll innerAll = choice.Items[i] as XmlSchemaAll;

                    if (childElement != null)
                    {
                        Console.Out.WriteLine("    Element/Type: {0}:{1}", childElement.Name,
                                              childElement.SchemaTypeName.Name);
                    }
                    else OutputElements(choice.Items[i] as XmlSchemaParticle);
                }

                Console.Out.WriteLine();
            }
            else if (all != null)
            {
                Console.Out.WriteLine("  All");
                for (int i = 0; i < all.Items.Count; i++)
                {
                    XmlSchemaElement childElement = all.Items[i] as XmlSchemaElement;
                    XmlSchemaSequence innerSequence = all.Items[i] as XmlSchemaSequence;
                    XmlSchemaChoice innerChoice = all.Items[i] as XmlSchemaChoice;
                    XmlSchemaAll innerAll = all.Items[i] as XmlSchemaAll;

                    if (childElement != null)
                    {
                        Console.Out.WriteLine("    Element/Type: {0}:{1}", childElement.Name,
                                              childElement.SchemaTypeName.Name);
                    }
                    else OutputElements(all.Items[i] as XmlSchemaParticle);
                }
                Console.Out.WriteLine();
            }
        }
        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);
        }
    }

}

And you can improve it for more specific cases. For example attributegroup, group, vs... Also now I got generic classes for that xsd. Now I gonna set the generic classes(which are made before) with an xml which is referenced by above xsd.

With these operations I'm gonna cancel the mecahnism which is read an xml node by node in my project.

OTHER TIPS

For a compiled XmlSchemaSet, I would use the following collections to go through global content (or named, as you're looking for xs:complexType name="carrierType" and xs:complexType name="productListType"):

For all others, such as attribute groups, groups, notations, you need to go down through each schema (the way you did for elements).

Also, you're going through PSVI properties. Just to make sure, maybe for other reading this, it is different than the "source" XSD. For e.g., AttributeUses is different than Attributes in ways that could make a difference for different requirements.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top