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

徘徊边缘 提交于 2021-02-07 04:09:55

问题


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.


回答1:


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.




回答2:


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"):

  • GlobalAttributes
  • GlobalElements
  • GlobalTypes - this is where your complex types are found.

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.



来源:https://stackoverflow.com/questions/11969063/how-to-parse-an-xsd-file-which-has-nested-elementscomplextype-and-simpletype-el

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!