Reputation: 3
I'm having trouble parsing the following soap response. This is my first time working with LINQ and must examples I've found use XML and not a SOAP envelope. How do I get the values of the different "items". I know there are different options (using add service reference) but it is not an option in my current project.
<SOAP-ENV:Envelope
xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"
xmlns:ns1=\"http://random.com/api/1/service\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
xmlns:ns2=\"http://xml.apache.org/xml-soap\"
xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"
SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">
<SOAP-ENV:Body>
<ns1:getBeatlesResponse>
<return xsi:type=\"ns2:Map\">
<item>
<key xsi:type=\"xsd:string\">error</key>
<value xsi:type=\"xsd:string\">OK</value>
</item>
<item>
<key xsi:type=\"xsd:string\">Beatles</key>
<value xsi:type=\"ns2:Map\">
<item>
<key xsi:type=\"xsd:int\">9</key>
<value xsi:type=\"xsd:string\">John Lennon</value>
</item>
<item>
<key xsi:type=\"xsd:int\">12</key>
<value xsi:type=\"xsd:string\">Paul McCartney</value>
</item>
<item>
<key xsi:type=\"xsd:int\">25</key>
<value xsi:type=\"xsd:string\">George Harrison</value>
</item>
<item>
<key xsi:type=\"xsd:int\">184</key>
<value xsi:type=\"xsd:string\">Ringo Starr</value>
</item>
</value>
</item>
</return>
</ns1:getBeatlesResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Thanks in advance
Upvotes: 0
Views: 5411
Reputation: 1911
this one is pretty tricky because you have items that have items which probably could have items too... so if you do something like this
var returnResult = (from r in document.Descendants("item")
select r).ToList();
you will get all the items separated and one which has all the values in one...
edit:
this works somewhat fine
XDocument document = XDocument.Load(@"XMLFile1.xml");
List<Item> items = new List<Item>();
var returnResult = (from r in document.Descendants("item")
select r).ToList();
foreach (XElement xElement in returnResult)
{
Item item = new Item();
item.Key = xElement.Element("key") != null ? xElement.Element("key").Value : "";
item.Value = xElement.Element("value") != null ? xElement.Element("value").Value : "";
items.Add(item);
}
//sort the list to get the one that have the rest to the end
var sorted = (from s in items
orderby s.Value.Length ascending
select s).ToList();
List<Item> finalList = new List<Item>();
items.Clear();
for (int i = 0; i < sorted.Count - 1; i++)
{
for (int j = 1; j < sorted.Count; j++)
{
if (sorted[j].Value.Contains(sorted[i].Value) &&
sorted[j].Value.Length > sorted[i].Value.Length)
{
Item itm = new Item();
itm.Key = sorted[j].Key;
KeyValuePair<string, string> kvp = new KeyValuePair<string, string>(sorted[i].Key,sorted[i].Value);
itm.Items.Add(kvp);
items.Add(itm);
}
else
{
if (!finalList.Contains(sorted[i]))
finalList.Add(sorted[i]);
}
}
}
class Item
{
public List<Item> Items { get; set; }
public string Key { get; set; }
public string Value {get;set;}
public Item()
{
Items = new List<Item>();
}
}
you can now see all sub items with their correct key... only the ok/error is making some trouble... but you can get them from the final list and pick them if they are not any of the key-value pairs...
hope this helps
Upvotes: 2
Reputation: 249
You should be able to parse this by loading it into an XDocument. Then you can select out the values you require by specifying the element names. Finally you could return these values as a new anonymous type. An example can be found in the response to this question: Using LINQ to XML to Parse a SOAP message
Let me know if you have any problems.
Upvotes: 0