2010-09-29 3 views
3

J'ai des documents XML (qui décrit une interface de service wsdl):Linq 2 xml: Comment récupérer les noms des méthodes web à partir d'un document wsdl?

<?xml version="1.0" encoding="utf-8"?> 
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> 
    <wsdl:types> 
    <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/"> 
     <s:element name="GetDummyType"> 
     <s:complexType> 
      <s:sequence> 
      <s:element minOccurs="0" maxOccurs="1" name="param1" type="s:string" /> 
      </s:sequence> 
     </s:complexType> 
     </s:element> 
     <s:element name="GetDummyTypeResponse"> 
     <s:complexType> 
      <s:sequence> 
      <s:element minOccurs="0" maxOccurs="1" name="GetDummyTypeResult" type="s:string" /> 
      </s:sequence> 
     </s:complexType> 
     </s:element> 
     <s:element name="SimplestWebService"> 
     <s:complexType /> 
     </s:element> 
     <s:element name="SimplestWebServiceResponse"> 
     <s:complexType> 
      <s:sequence> 
      <s:element minOccurs="0" maxOccurs="1" name="SimplestWebServiceResult" type="s:string" /> 
      </s:sequence> 
     </s:complexType> 
     </s:element> 
     <s:element name="SignInComp"> 
     <s:complexType /> 
     </s:element> 
     <s:element name="SignInCompResponse"> 
     <s:complexType> 
      <s:sequence> 
      <s:element minOccurs="0" maxOccurs="1" name="SignInCompResult" type="s:string" /> 
      </s:sequence> 
     </s:complexType> 
     </s:element> 

...

Deux opérations que je dois effectuer sur le XML ci-dessus:

  1. récupérer tous les noms d'éléments (GetDumm yType, SimplestWebService, etc.) Ce sont les noms des méthodes (ils ne se terminent pas par "Réponse").
  2. récupérer par son nom de params d'une méthode (param1 pour GetDummyType etc.)

J'ai réussi jusqu'à présent que pour analyser ce document comme XmlDocument:

XmlDocument doc = new XmlDocument(); 
doc.LoadXml(result.ToString()); 

(je sais que ce n'est pas beaucoup)

Je ne peux pas comprendre comment ce XML est mappé à quelque chose que vous pouvez utiliser linq sur ..
Comment faites-vous cela?

Merci.

Répondre

5

Vous devez vous assurer d'utiliser les espaces de noms XML corrects dans les requêtes. En outre, pour LINQ to XML, utilisez XDocument, et non XmlDocument, qui est ancien System.Xml.

C'est ce que j'ai réussi à arriver à ce jour:

XDocument doc = XDocument.Parse(xml); 
XNamespace wsdl = "http://schemas.xmlsoap.org/wsdl/"; 
XNamespace s = "http://www.w3.org/2001/XMLSchema"; 

var schema = doc.Root 
    .Element(wsdl + "types") 
    .Element(s + "schema"); 

var elements = schema.Elements(s + "element"); 
Func<XElement, string> getName = (el) => el.Attribute("name").Value; 

// these are all method names 
var names = from el in elements 
      let name = getName(el) 
      where !name.EndsWith("Response") 
      select name; 

string methodName = "GetDummyType"; 
var method = elements 
    .Single(el => getName(el) == methodName); 

// these are all parameters for a given method 
var parameters = from par in method.Descendants(s + "element") 
       select getName(par); 

J'ai testé ce code et il fonctionne sur vos données.
Cependant, je ne suis pas tout à fait la solution la plus simple qui soit, donc j'accueille toutes les suggestions pour raccourcir le code.

Best,
Dan

+0

Juste Pour votre information: Minor glitch (retourné quelques noms de méthodes non pertinents) que j'ai résolu par: var methodsNamesElements = elements.Where (x => x.Descendants(). Count()! = 0); et se disperse sur methodsNamesElements au lieu d'éléments. Mais à part ça - fonctionne comme un charme! Merci beaucoup. –

2

pour # 1, en utilisant l'ensemble System.Linq.Xml vous pouvez faire qqch comme:

List<string> names = new List<string>(); 
XDocument doc = Xdocument.Parse(result.ToString()); 
foreach (XElement element in doc.Elements("wsdl:types").First().Elements("s:schema").First().Elements("s:element")) 
{ 
    names.Add(element.Attributes("name").First().Value); 
} 

il n'a pas été testé et vous pouvez avoir à régler un peu le code;)

BTW, vous pouvez trouver plus d'informations sur msdn concerning System.Xml.Linq

0

LINQ pour XML, vous pouvez faire quelque chose comme ça -

XDocument doc = XDocument.Parse(xmlstring); 
var methods = from methods in doc.Descendants("s:element") 
       where !methods.Attribute("name").Value.EndsWith("Resopnse") 
       select methods; 
     var methodNames = (from method in methods 
          select method.Attribute("name").Value).ToList(); 
     var paramList = from type in methods.Descendants("s:complexType") 
         from param in type.Descendants("s:sequence") 
         where type.HasElements && type.Parent.Attribute("name").Value == somemethodname 
         select new { Name = param.Attribute("name").Value }; 

ajouter une référence à System.Core et System.Xml.Linq

+1

Salut! Je voudrais faire quelques commentaires concernant votre code.Premièrement, vous ** ne pouvez pas interroger les éléments avec des espaces de noms par ns: convention d'élément **. Vous devez spécifier explicitement les espaces de noms, voir MSDN: http://msdn.microsoft.com/en-us/library/bb387075.aspx. Deuxièmement, pourquoi utiliseriez-vous plusieurs fois Descendants sur une méthode? Si vous souhaitez reproduire exactement la hiérarchie, vous devez utiliser les méthodes d'extension Element (s) car elles garantissent que la structure est la même que vous imaginez. Sinon, method.Descendants ("s: element") retournerait tous les paramètres de la méthode, même s'ils sont plus profonds. –

Questions connexes