I have a XML documents (which describes a wsdl service's interface):
<?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>
...
Two operations I need to perform on the above xml:
- retrieve all elements names (GetDummyType, SimplestWebService etc.) Those are the methods names (they don't end with "Response").
- retrieve a method's params by it's name (param1 for GetDummyType etc.)
I've managed so far only to parse this document as an XmlDocument:
XmlDocument doc = new XmlDocument();
doc.LoadXml(result.ToString());
(I know that's not much)
I just can't figure out how that XML is mapped to something you can use linq on..
How do you do that?Thanks.
You need to make sure to use correct XML namespaces in queries.
Also, for LINQ to XML, use XDocument
, not XmlDocument
, which is from old System.Xml
.
This is what I managed to come up with so far:
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);
I have tested this code and it works on your data.
However I am not entirely it is the simplest solution there is so I welcome any suggestions to shortening the code.
Best,
Dan
for #1, using the assembly System.Linq.Xml
you could do sth like:
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);
}
it isn't tested so you may have to tune a bit the code ;)
BTW, you may find more information on msdn concerning System.Xml.Linq
using linq to xml you can do something like this -
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 };
add reference to system.core and system.xml.linq
精彩评论