2010-12-15 84 views
5

我試圖解析WSDL,沿着給出的例子here解析複雜的WSDL參數信息

作者在評論中指出,該示例不能深入到複雜的數據類型中。

而事實上,當我運行這個例子時,它甚至沒有處理簡單的數據類型。

我已經在System.Web.Services.Description.ServiceDescription類中使用過,但是在運行時找不到任何實際參數或返回類型信息。我收集到我可能需要手動解析一個xsd文件?

谷歌和stackoverflow似乎都缺乏一個完整的例子,如何深入到複雜的類型編程,所以...我應該怎麼做?

回答

16

這是不漂亮 - 但它能夠完成任務(希望)。我將這段代碼部分地基於您提供的鏈接,然後添加了一些遞歸來解析模式中包含的不同類型,以及內部元素及其數據類型。這絕對不考慮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

馬丁,我試過你的代碼,但XmlSchema xmlSchema = types.Schemas [0];始終爲空。 – 2011-03-24 15:11:36

+0

@ user465876:我最好的猜測是你的URL沒有正確指向WSDL。希望有所幫助! – pmartin 2011-03-24 16:23:47

+0

我該如何檢查?我用「?wsdl」打開服務網址並打開。此外,在發佈的原始示例中,我的wsdl被解析,並且獲得了所有簡單的數據類型。還有什麼我可能會失蹤? – 2011-03-24 20:42:45

1

你想對解析結果做什麼?例如,如果您想將類型存入內存以使用它們,您可以使用ServiceDescription.Read和導入程序來編譯程序集。

你可以看到在這個PowerShell腳本這種做法的一個例子:

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

+0

我寧願做一些比編譯程序集更輕的東西。我不一定想對結果做任何事情,我只需要參數和返回類型的列表(直到原子級別)。 – jaws 2010-12-21 16:51:14