monodevelop parse soap response - c#

been reading this and others forums for hours and days now and can't find a solution for my soap response. Been trying all kinds of answers here, but can't parse my response :(
my response :
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<getLocationsResponse xmlns="http://getlocations.ws.hymedis.net">
<locs>
<loc>
<name>Zeebrugge Wielingen Zand</name>
<abbr>ZWZ</abbr>
<RDX>1435.8</RDX>
<RDY>378678.6</RDY>
<params>
<param>GHs</param>
<param>SS10</param>
</params>
</loc>
</locs>
</getLocationsResponse>
</soapenv:Body>
</soapenv:Envelope>
My c# code so far (param soapresponse is the whole soapresponse in string format) my response is correct, so the full xml soap response, but can't parse it good
public void readXml(string soapresponse){
XmlDocument xmlresponse = new XmlDocument();
xmlresponse.LoadXml(soapresponse);
XmlNamespaceManager nsmanager = new XmlNamespaceManager(xmlresponse.NameTable);
nsmanager.AddNamespace ("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
XmlNodeList nodes = xmlresponse.SelectNodes("/soapenv:Envelope/soapenv:Body/getLocationsResponse/locs/loc", nsmanager);
List<Locatie> locatielijst = new List<Locatie>();
// loop
foreach(XmlNode node in nodes){
string loc_naam = node["name"].InnerText;
string loc_code = node["abbr"].InnerText;
...
Locatie locatie = new Locatie();
locatie.loc_naam = loc_naam;
locatie.loc_code = loc_code;
...
locatielijst.Add (locatie);
}
Console.WriteLine(locatielijst.Count.ToString());
foreach(Locatie loc in locatielijst){
Console.WriteLine (loc.loc_code);
}
}
but every time my list.count returns 0 -> so no data in them.. plz help me out!

The following code might work.
public class MainClass
{
public static void Main(string[] args)
{
var response = new FileStream("Response.xml", FileMode.Open);
XDocument doc = XDocument.Load(response);
XNamespace xmlns = "http://getlocations.ws.hymedis.net";
var nodes = doc.Descendants(xmlns + "locs")
.Elements(xmlns + "loc");
var list = new List();
foreach (var node in nodes)
{
list.Add(new Location {
Name = node.Element(xmlns + "name").Value,
Code = node.Element(xmlns + "abbr").Value
});
}
foreach (var item in list) {
Console.WriteLine(item.Code);
}
}
public class Location
{
public string Code { get; set; }
public string Name { get; set; }
}
}
I don't have much experience with mono but .net made it very easy to consume WCF SOAP services.
This article explains how to generate the proxy classes for a WCF service:
http://johnwsaunders3.wordpress.com/2009/05/17/how-to-consume-a-web-service/
I hope this helps.
Regards,
Wouter Willaert

Related

How do I get a specific element in a XML document?

I have a XML file that looks like this:
<Info>
<ID>1</ID>
<Result>
<ID>2</ID>
</Result>
</Info>
I want to count how many Info/Result/ID I have in this file.
I am doing this:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("myFile.xml");
xmlNodeList MyList = xmlDoc.GetElementsByTagName("Info/Result/ID");
int totalCount = MyList.Count;
// other logic...
The method GetElementsByTagName does not find any "ID"-field.
I want to get the "ID = 2".
How do I do that?
To count all the nodes in "Info/Result/ID" path use this..
var count = xmlDoc.SelectNodes("Info/Result/ID")?.Count ?? 0;
To process these nodes
var nodes = xmlDoc.SelectNodes("Info/Result/ID");
foreach (XmlNode node in nodes) {
var idValue = node.InnerText
// do something
}
Got it working, here´s how:
public static void MyCountExample(string myXml, out int myID)
{
var stream = new MemoryStream(Encoding.UTF8.GetBytes(myXml ?? ""));
var reader = XmlReader.Create(stream);
myID= 0;
reader.IsStartElement("Info");
while (!reader.EOF)
{
if (reader.ReadToFollowing("Result"))
{
if (reader.ReadToDescendant("ID"))
{
myID++;
else
{
return somethingElse();
}
......

read xml file on c#, reading the arabic text provide a encrypted string not actual utf-8

xml file-> for example this is hosted on the url http://localhost/test1
<?xml version="1.0" encoding="utf-8"?>
<MSG>
<arabic>
<translationOne>اول</translationOne>
<translationTwo>دوم</translationTwo>
</arabic>
<persian>
<translationOne>یک</translationOne>
<translationTwo>دوم</translationTwo>
</persian>
</MSG>
c# class
var m_strFilePath = "http://localhost/test1";
string xmlStr;
using (var wc = new WebClient())
{
xmlStr = wc.DownloadString(m_strFilePath);
}
var xmldoc = new XmlDocument();
xmldoc.LoadXml(xmlStr);
XmlNodeList unNodeA = xmldoc.SelectNodes("MSG/arabic");
XmlNodeList unNodeP = xmldoc.SelectNodes("MSG/persian");
string arabic = "";
foreach (XmlNode i in unNodeA)
{
arabic += i["translationOne"].InnerText;
}
string persian= "";
string persian2 ="";
foreach (XmlNode ii in unNodeP)
{
persian+= ii["translationOne"].InnerText;
persian2+= ii["translationTwo"].InnerText;
}
->>print(arabic and persian);
here the test contain not correct format like (اول دوم) it's some kind of (عبد العزيز عباسین)
It is better to use LINQ to XML API. It is available in the .Net Framework since 2007.
c#
void Main()
{
XDocument xdoc = XDocument.Parse(#"<?xml version='1.0' encoding='utf-8'?><MSG>
<arabic>
<translationOne>اول</translationOne>
<translationTwo>دوم</translationTwo>
</arabic>
<persian>
<translationOne>یک</translationOne>
<translationTwo>دوم</translationTwo>
</persian>
</MSG>");
foreach (XElement elem in xdoc.Descendants("arabic").Elements())
{
Console.WriteLine("translation: {0}", elem.Value);
}
}
If you need to load XML from the URL:
const string Url = #"http://hurt.super-toys.pl/xml/super_toys_ceneo_pelny.xml";
XDocument xdoc = XDocument.Load(Url);
Output
translation: اول
translation: دوم

Navigate xml nodes;

Hi I have an xml data returned from another service. It looks like this
<?xml version="1.0" encoding="UTF-8"?>
<response xmlns="http://test.com/group/application" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Response>
<Response>
<ReturnCode>0</ReturnCode>
<Message>Sucess</Message>
<Data>PRINT 'This is a test #2'</Data>
</Response>
</Response>
</response>
I need the value of Data, Message and ReturnCode. The value inside the Data(PRINT 'This is a test #2') node could be single line or thousands of lines..
I am using this C# code to get the values
XmlDocument xm = new XmlDocument();
string Response = obj.getContent(str, 1, 73810, SHA);
//Console.WriteLine("Response" + Response);
xm.LoadXml(Response);
Console.WriteLine(xm.InnerXml);
XmlNode oldCd;
XmlElement root = xm.DocumentElement;
Console.WriteLine(root.InnerText);
oldCd = root.SelectSingleNode("/response/Response/Response/ReturnCode/Message/Data/");
static void Main()
{
try
{
svc obj = new svc();
..
//XmlDocument xm = new XmlDocument();
string rsp = obj.getContent(..;
String myEncodedString;
myEncodedString = obj.XmlDecode(rsp);
XNamespace xmlns = XNamespace.Get("http://xxxx.com/xxx/xx");
XDocument doc = XDocument.Parse(myEncodedString);
Console.WriteLine(obj.Return_Message_Data("ReturnCode", myEncodedString));
Console.WriteLine(obj.Return_Message_Data("Message", myEncodedString));
Console.WriteLine(obj.Return_Message_Data("Data", myEncodedString));
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
Try this
XmlDocument xml = new XmlDocument();
xml.LoadXml(myXmlString); //myXmlString is the xml file in string //copying xml to string: string myXmlString = xmldoc.OuterXml.ToString();
XmlNodeList xnList = xml.SelectNodes("/responset[#*]/Response");
foreach (XmlNode xn in xnList)
{
XmlNode response = xn.SelectSingleNode("Response");
if (response != null)
{
string rc = response["ReturnCode"].InnerText;
string msg = example["Message"].InnerText;
string data = example["Data"].InnerText;
}
}

Get data from XML in simple way

I am using the following code to get data from the OData XML and its works ,
but I am not sure that I fully understand it so maybe there is a way to write it in simple way?
what i need is to get the property value which is in the first loop value = 0001 and text = approve and in the
second value = 0002 text = reject
The code
XNamespace dns = "http://schemas.microsoft.com/ado/2007/08/dataservices";
if (response.StatusCode == HttpStatusCode.OK)
{
string decisionOptions = ReadResponse(response);
XDocument document = XDocument.Parse(decisionOptions);
foreach (XElement element in document.Element(dns + "DecisionOptions").Elements(dns + "element"))
{
PropertyKeyRef decisionOption = new PropertyKeyRef();
decisionOption.PropertyValue = element.Element(dns + "DecisionKey").Value;
decisionOption.PropertyName = element.Element(dns + "DecisionText").Value;
dat.Add(decisionOption);
}
}
the XML
<?xml version="1.0" encoding="utf-8" ?>
- <d:DecisionOptions xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
- <d:element m:type="TAS.DecisionOption">
<d:InstanceID>007</d:InstanceID>
<d:DecisionKey>0001</d:DecisionKey>
<d:DecisionText>Approve</d:DecisionText>
<d:CommentMandatory>false</d:CommentMandatory>
<d:Nature>POSITIVE</d:Nature>
</d:element>
- <d:element m:type="TAS.DecisionOption">
<d:InstanceID>007</d:InstanceID>
<d:DecisionKey>0002</d:DecisionKey>
<d:DecisionText>Reject</d:DecisionText>
<d:CommentMandatory>true</d:CommentMandatory>
<d:Nature>NEGATIVE</d:Nature>
</d:element>
</d:DecisionOptions>
here how can do it in simple way using LINQ
namespace ConsoleApplication7
{
class Program
{
static void Main(string[] args)
{
XDocument xdoc = XDocument.Load("test.xml");
XNamespace dns = "http://schemas.microsoft.com/ado/2007/08/dataservices";
//in xml every element should have it's namespace for this reason I have to concatenate namespace with the name of element
var elementsRes = xdoc.Root.Elements(dns+"element").Select((elt) => new PropertyKeyRef { PropertyName = elt.Element(dns+"DecisionKey").Value.ToString(),PropertyValue = elt.Element(dns+"DecisionText").Value.ToString() }).ToList();
foreach (var item in elementsRes)
{
//your code for the result
}
}
}
public class PropertyKeyRef
{
public string PropertyName
{ get; set; }
public string PropertyValue
{ get; set; }
}
}
You have already achieved it in simplest way. Little bit of LINQ might improve readability (get away with foreach loop) but it's just syntactic sugar of what you have written.
XNamespace dns = "http://schemas.microsoft.com/ado/2007/08/dataservices";
XDocument document = XDocument.Load("database.xml");
PropertyKeyRef decisionOption = new PropertyKeyRef();
decisionOption.PropertyValue = document.Descendants(dns + "DecisionKey")
.Select(node => node.Value).First();
decisionOption.PropertyName = document.Descendants(dns + "DecisionText")
.Select(node => node.Value).First();
dat.Add(decisionOption);

Reading SOAP xml answer

I have to read a SOAP answer from the file below
<?xml version="1.0"?>
<Envelopes>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Body>
<env:Fault>
<env:Code>
<env:Value>env:Receiver</env:Value>
<env:Subcode>
<env:Value>-1</env:Value>
</env:Subcode>
</env:Code>
<env:Reason>
<env:Text xml:lang="en">CServiceData::SetPropertyValue failed; '</env:Text>
</env:Reason>
<env:Detail>
<Object>4</Object>
<ObjectIndex>1</ObjectIndex>
<Command>AddObject</Command>
<SessionID>B8FE2330-4252-4BB1-A3EE-053F4413A0C0</SessionID>
</env:Detail>
</env:Fault>
</env:Body>
</env:Envelope>
</Envelopes>
I only need the content of the Text tag CServiceData::SetPropertyValue failed;
You can use XPath:
public string GetErrorMessage(string xml)
{
using (StringReader sr = new StringReader(xml))
{
var doc = new XPathDocument(sr);
var nav = doc.CreateNavigator();
var xmlNs = new XmlNamespaceManager(nav.NameTable);
xmlNs.AddNamespace("env", #"http://www.w3.org/2003/05/soap-envelope");
var node = nav.SelectSingleNode("//env:Text", xmlNs);
return node.Value;
}
}
or you can use LINQ To XML:
public string GetErrorMessage(string xml)
{
var doc = XDocument.Parse(xml);
var node = doc.Descendants(XName.Get("Text", #"http://www.w3.org/2003/05/soap-envelope"))
.FirstOrDefault();
return node.Value;
}

Categories

Resources