解析复杂的WSDL参数信息

时间:2010-12-15 17:05:54

标签: c# xsd wsdl

我试图按照here给出的示例解析WSDL。

作者在评论中指出,该示例无法深入研究复杂的数据类型。

事实上,当我运行该示例时,它似乎甚至不能处理简单的数据类型。

我在System.Web.Services.Description.ServiceDescription类中进行了调查,该类在示例中使用,但在运行时无法找到任何实际参数或返回类型信息。我知道我可能需要对xsd文件进行一些手动解析吗?

谷歌和stackoverflow似乎缺乏一个如何以编程方式深入研究复杂类型的完整示例,因此......我应该怎么做?

2 个答案:

答案 0 :(得分:19)

这不是很好 - 但它完成了工作(希望如此;)。我将此代码部分基于您提供的链接,然后添加一些递归来解析模式中包含的不同类型,以及内部元素及其数据类型。这绝对没有考虑到XML模式中的所有可能性,但我认为它足以说明如果需要可以增加复杂性。

我希望这会有所帮助!!!!

internal class Program
{
    private static void Main(string[] args)
    {
        //Build the URL request string
        UriBuilder uriBuilder = new UriBuilder(@"http://digicomdev:8888/digitalOrderBroker/digitalOrderBroker.asmx");
        uriBuilder.Query = "WSDL";

        HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(uriBuilder.Uri);
        webRequest.ContentType = "text/xml;charset=\"utf-8\"";
        webRequest.Method = "GET";
        webRequest.Accept = "text/xml";

        //Submit a web request to get the web service's WSDL
        ServiceDescription serviceDescription;
        using (WebResponse response = webRequest.GetResponse())
        {
            using (Stream stream = response.GetResponseStream())
            {
                serviceDescription = ServiceDescription.Read(stream);
            }
        }

        //Loop through the port types in the service description and list all of the 
        //web service's operations and each operations input/output
        foreach (PortType portType in serviceDescription.PortTypes)
        {
            foreach (Operation operation in portType.Operations)
            {
                Console.Out.WriteLine(operation.Name);

                foreach (var message in operation.Messages)
                {
                    if (message is OperationInput)
                        Console.Out.WriteLine("Input Message: {0}", ((OperationInput) message).Message.Name);
                    if (message is OperationOutput)
                        Console.Out.WriteLine("Output Message: {0}", ((OperationOutput) message).Message.Name);

                    foreach (Message messagePart in serviceDescription.Messages)
                    {
                        if (messagePart.Name != ((OperationMessage) message).Message.Name) continue;

                        foreach (MessagePart part in messagePart.Parts)
                        {
                            Console.Out.WriteLine(part.Name);
                        }
                    }
                }
                Console.Out.WriteLine();
            }
        } //End listing of types

        //Drill down into the WSDL's complex types to list out the individual schema elements 
        //and their data types
        Types types = serviceDescription.Types;
        XmlSchema xmlSchema = types.Schemas[0];

        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);
                        }
                    }
                }
            }
            else if (complexType != null)
            {
                Console.Out.WriteLine("Complex Type: {0}", complexType.Name);
                OutputElements(complexType.Particle);
            }
            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();
        }
    }
}

答案 1 :(得分:1)

您想对解析后的结果做什么?例如,如果要将类型存入内存以便使用它们,可以使用ServiceDescription.Read和导入程序来编译程序集。

您可以在此PowerShell脚本中看到此类方法的示例:

http://www.leeholmes.com/blog/2007/02/28/calling-a-webservice-from-powershell/