【问题标题】:How to parse an xsd file which has nested elements(complexType and simpleType elements and attributes)?如何解析具有嵌套元素(complexType 和 simpleType 元素和属性)的 xsd 文件?
【发布时间】:2012-08-11 17:37:09
【问题描述】:

我有一个这样的 xsd 文件:

<?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>

我有这样的代码:

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

当我尝试运行它时,它给了我第一个元素的元素名称。 之后,我如何获取其他两个 xs:complexType name="carrierType" 和 xs:complexType name="productListType" 及其子元素和属性?

我做了这部分,并会更新代码。

我还想用这些数据和数据类型创建一个通用类。我该怎么办?

感谢您的提前。

【问题讨论】:

    标签: c# xsd schema complextype


    【解决方案1】:

    如果你有一个像上面这样的 xsd 文档,你可能需要这样的代码。

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

    您可以针对更具体的情况对其进行改进。 例如属性组、组、vs... 现在我也得到了那个 xsd 的通用类。 现在我将使用上面 xsd 引用的 xml 设置通用类(之前制作的)。

    通过这些操作,我将取消在我的项目中逐个节点读取 xml 的机制。

    【讨论】:

      【解决方案2】:

      对于已编译的 XmlSchemaSet,我将使用以下集合来遍历全局内容(或命名,如您正在寻找的 xs:complexType name="carrierType" and xs:complexType name="productListType"):

      对于所有其他,例如属性组、组、符号,您需要遍历每个架构(就像您对元素所做的那样)。

      另外,您正在浏览 PSVI 属性。只是为了确保,也许对于其他阅读,它与“源”XSD 不同。例如,AttributeUsesAttributes 的不同之处在于可能会因不同的要求而有所不同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-06
        • 2012-06-24
        • 2023-03-23
        • 2014-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多