c# get values from xml response - c#

I am trying to get values from xml respone :
<?xml version="1.0" encoding="utf-8"?>
<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://adaddaasd.com">
<A>14</A>
<B>Failed</B>
<C>22</C>
</Response>
My code is :
string responseString = await response.Content.ReadAsStringAsync();
var xDocument = XDocument.Parse(responseString);
var responseNode = xDocument.XPathSelectElement("/Response");
var A = xDocument.XPathSelectElement("/Response/A");
But I am getting null values for A and responseNode. Whats wrong? Thanks

You're blatantly ignoring the XML namespace that's defined in your XML document:
<Response xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns='http://adaddaasd.com'>
****************************
You need to include that into your querying - I would try to do it like this:
var xDocument = XDocument.Parse(responseString);
// *define* your XML namespace!
XNamespace ns = "http://adaddaasd.com";
// get all the <Response> nodes under the root with that XML namespace
var responseNode = xDocument.Descendants(ns + "Response");
// from the first <Response> node - get the descendant <A> nodes
var A = responseNode.FirstOrDefault()?.Descendants(ns + "A");
If you insist on using the XPathSelectElement method, then you must define an XmlNamespaceManager and use it in your XPath select:
// define your XML namespaces
XmlNamespaceManager xmlnsmgr = new XmlNamespaceManager(new NameTable());
xmlnsmgr.AddNamespace("ns", "http://adaddaasd.com");
// use the defined XML namespace prefix in your XPath select
var A = xDocument.XPathSelectElement("/ns:Response/ns:A", xmlnsmgr);

Related

Get Specific Tag value From Complex Xml in Xdocument in asp.net

As I am a Beginner i Certainly need your Help.
I want to get a Specific Tag from Xdocument.
Following is the Content in the Xdocument:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<UcicLoginResponse xmlns="http://tempuri.org/">
<UcicLoginResult>
<Success>true</Success>
<authToken>xxxxxxx</authToken>
</UcicLoginResult>
</UcicLoginResponse>
</soap:Body>
</soap:Envelope>
Then I want to get the Value of the tag authToken.
Tried Lot with Descentants and Elements..But,due to the xml attributes,All tries leds to error.Anyone pls Help me...
Some of my tries Given:
XDocument _Xresult = XDocument.Parse(XmlResponse.Elements().Single().Value);
IEnumerable<XElement> xResponseItem = _Xresult.Descendants("UcicLoginResult");
if (xResponseItem.Descendants("Remarks").Any())
{
string sErr = _Xresult.Element("Remarks").Value;
throw new Exception("Authentication failed : " + sErr);
}
token = _Xresult.Descendants("authToken").FirstOrDefault().Value;
#
var root = XmlResponse.Root;
var res1= root.Elements("UcicLoginResult").Elements("authToken").FirstOrDefault().Value;
#
var resp=XmlResponse.Descendants("soap:Envelope").Descendants("soap:Body").Descendants("UcicLoginResponse").Descendants("UcicLoginResult").Elements("authToken");
#
IEnumerable<XElement> xResponseItem =XmlResponse.Descendants("UcicLoginResponse");
string sErr = xResponseItem.Descendants("UcicLoginResult").FirstOrDefault().Element("authToken").Value;
#
var res = XmlResponse.Descendants("soap:Envelope").Descendants("soap:Body").Descendants("UcicLoginResponse").Descendants("UcicLoginResult").Elements("authToken");
You are not specifying the namespace. http://tempuri.org/;
var xDocument = XDocument.Parse(xml);
XNamespace ns = "http://tempuri.org/";
var authToken = xDocument.Descendants(ns + "authToken").FirstOrDefault();
I don't know the xml where is it come from but it seems that you are communicating with a SOAP service and it could be better to get the data as object based by WCF client.

Cannot parse XML with xmlns value

I receive an XML file which has on the root node a xmlns namespace assigned:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Message xmlns="http://www.myAddress.com/DataRequest/message/">
<Date>2017/01/01</Date>
</Message>
I do not know how to retrive the Date element using XPath, I tried
var root = xDocument.Root;
var dateElement = root.XPathSelectElement("/Message/Date");
If I remove the namespace from the root xml, then I can retrieve the value using "/Message/Date".
I tried to add xmlns to a XmlNamespaceManager, but I get this error:
Prefix "xmlns" is reserved for use by XML.
How can I get the value?
You should use namespace when you specify element's name. Default namespace is easy to get with XElement.GetDefaultNamespace() method:
var ns = root.GetDefaultNamespace();
var dateElement = (DateTime)root.Element(ns + "Date");
If you want to use XPath:
XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());
manager.AddNamespace("ns", root.GetDefaultNamespace().ToString());
var dateElement = (DateTime)root.XPathSelectElement("/ns:Message/ns:Date", manager);
I would suggest using LINQ.
Here is a link to the code example:https://msdn.microsoft.com/en-us/library/mt693115.aspx
here is the code:
XElement root = XElement.Load("Message.xml");
IEnumerable<XElement> dateNode=
from el in root.Elements("Date")
select el;
foreach (XElement el in dateNode)
Console.WriteLine(el);

How to Extract an Element using XPathSelectElement

I am extracting an element from an xml document but it's returning null
<?xml version="1.0" encoding="utf-8"?>
<Test1
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-test"
xmlns="https://www.google.com/partner/testt.xsd">
<Test2>OK</Test2>
<Test3>1439379003</Test3>
</Test1>
I'm trying to extract test2 element but its returning null
var responseXdoc = XDocument.Parse(response);
var statusElement = responseXdoc.XPathSelectElement("/Test1/Test2");
result statusElement as null but I'm expecting Ok
Problem in Namespace
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://www.google.com/partner/testt.xsd (Its my guess)
Your XML has default namespace which elements in the scope inherit implicitly. To reference elements in namespace using XPath, you need to use namespace prefix which, you need to register before in an XmlNamespaceManager :
var nsManager = new XmlNamespaceManager(new NameTable());
nsManager.AddNamespace("d", "https://www.insuranceleads.com/partner/PricePresentationResult.xsd");
var statusElement = responseXdoc.XPathSelectElement("/d:Test1/d:Test2", nsManager);
dotnetfiddle demo
Alternatively, you can use XNamespace and LINQ API to do the same, for example :
XNamespace d = "https://www.insuranceleads.com/partner/PricePresentationResult.xsd";
var statusElement = responseXdoc.Element(d + "Test1").Element(d + "Test2");

Cannot get XPath to work with unnamed namespace

The XML (fragment):
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetXMLResponse xmlns="http://sitecore.net/visual/">
<GetXMLResult>
<sitecore xmlns="">
<status>ok</status>
The code (fragment):
XmlNamespaceManager nsManager = new XmlNamespaceManager(template.NameTable);
nsManager.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
nsManager.PushScope();
XmlNode sitecoreRoot = template.SelectSingleNode("/soap:Envelope/soap:Body/*[namespace-uri()='http://sitecore.net/visual/' and local-name()='GetXMLResponse']", nsManager);
string status = sitecoreRoot.SelectSingleNode("/GetXMLResult/sitecore/status").Value;
sitecoreRoot element returns the correct node. However the XPath to get the status always returns null, even though the siteCoreRoot.OuterXMl property shows the element is present.
The only thing I can think of is the line:
<sitecore xmlns="">
is throwing off the XPath
TIA
XmlNamespaceManager ns = new XmlNamespaceManager(cd.NameTable);
ns.AddNamespace("sp", "http://schemas.xmlsoap.org/soap/envelope/");
ns.AddNamespace("sc", "http://sitecore.net/visual/");
XmlNode sitecoreRoot = cd.SelectSingleNode("//sp:Envelope/sp:Body/sc:GetXMLResponse/sc:GetXMLResult/sitecore/status", ns);
var status = sitecoreRoot.InnerText;
May help you?
If you just want the status node, you can try this xml library and the following XPath.
XElement root = XElement.Load(file); // or .Parse(string)
XElement status = root.XPathElement("//status");
The library handles doing the namespace for you.

Using C# to parse a SOAP Response

I am trying to get the values for faultcode, faultstring, and OrderNumber from the SOAP below
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Body>
<faultcode>1234</faultcode>
<faultstring>SaveOrder:SetrsOrderMain:Cannot change OrderDate if GLPeriod is closed, new OrderDate is 3/2/2010:Ln:1053</faultstring>
<detail>
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Body UserGUID="test">
<m:SaveOrder xmlns:m="http://www.test.com/software/schema/" UserGUID="test">
<Order OrderNumber="1234-1234-123" Caller="" OrderStatus="A" xmlns="http://www.test.com/software/schema/">
Here is my code in C#
XDocument doc = XDocument.Load(HttpContext.Current.Server.MapPath("XMLexample.xml"));
var errorDetail = new EcourierErrorDetail
{
FaultCode = from fc in doc.Descendants("faultcode")
select fc.Value,
FaultString = from fs in c.Descendants("faultstring")
select fs.Value,
OrderNumber = from o in
doc.Descendants("detail").Elements("Order").Attributes("OrderNumber")
select o.Value
};
return errorDetail;
I am able to get the values for both faultcode and faultstring but not the OrderNumber. I am getting "Enumeration yielded no results." Can anyone help? Thanks.
Yes, you're ignoring the XML namespace when selecting:
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
.....
<m:SaveOrder xmlns:m="http://www.test.com/software/schema/" UserGUID="test">
<Order OrderNumber="1234-1234-123" Caller="" OrderStatus="A" xmlns="http://www.test.com/software/schema/">
The <Order> tag is inside the <m:SaveOrder> tag which uses the XML namespace prefixed by the m: prefix.
Also, you're trying to select the "detail" and then you skip to the "Order" node directly (using .Elements()) - you missed the <m:SaveOrder> node in between.
You need to take that into account when selecting:
XDocument doc = XDocument.Load(HttpContext.Current.Server.MapPath("XMLexample.xml"));
XNamespace xmlns = "http://www.test.com/software/schema/";
var orderNode = doc.Descendants(xmlns + "SaveOrder").Elements(xmlns + "Order");
var value = from o in orderNode.Attributes("OrderNumber")
select o.Value;
Does that give you a result??
A clean solution could be using System.Xml.XPath. Here is where I found the example
This is how to use it in this case:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(result);
XmlNamespaceManager xmlnsManager = new XmlNamespaceManager(xmlDoc.NameTable);
xmlnsManager.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
xmlnsManager.AddNamespace("m", "http://www.test.com/software/schema/");
var orderNode = xmlDoc.SelectSingleNode("//m:Order", xmlnsManager);
var value = orderNode.Attributes["OrderNumber"].Value;

Categories