Reputation: 4662
I'm having a heck of a time parsing this layout:
<string xmlns="http://www.namespaceuri.com/Admin/ws">
<CardTrxSummary>
<PaymentMethod>
<Payment_Type_ID>VISA </Payment_Type_ID>
<Authorization>0.0000</Authorization>
<Capture>0.0000</Capture> <ForceCapture>0.0000</ForceCapture>
<PostAuth>0.0000</PostAuth> <Return>0.0000</Return>
<Sale>3419.2700</Sale> <Receipt>0.0000</Receipt>
<RepeatSale>0.0000</RepeatSale>
<Activate>0.0000</Activate>
<Deactivate>0.0000</Deactivate>
<Reload>0.0000</Reload>
<Authorization_Cnt>0</Authorization_Cnt>
<Capture_Cnt>0</Capture_Cnt>
<ForceCapture_Cnt>0</ForceCapture_Cnt>
<PostAuth_Cnt>0</PostAuth_Cnt>
<Return_Cnt>0</Return_Cnt>
<Sale_Cnt>13</Sale_Cnt>
<Receipt_Cnt>0</Receipt_Cnt>
<RepeatSale_Cnt>0</RepeatSale_Cnt>
<Activate_Cnt>0</Activate_Cnt>
<Deactivate_Cnt>0</Deactivate_Cnt>
<Reload_Cnt>0</Reload_Cnt>
<Cnt>13</Cnt>
</PaymentMethod>
</CardTrxSummary>
</string>
I am trying with this code to get the a specific result:
private static string ReadValueFromXml(XmlDocument xmlDocument, string field)
{
var xdoc = xmlDocument.ToXDocument();
var ns = "http://www.namespaceuri.com/Admin/ws";
return xdoc.Descendants(ns + "PaymentMethod")
.Select(x => (string) x.Attribute("Cnt"))
.FirstOrDefault();
}
At this point, it's giving me this message:
The ':' character, hexadecimal value 0x3A, cannot be included in a name.
I tried it this way:
XmlNodeList xnList = xmlDocument.SelectNodes("/CardTrxSummary/PaymentMethod");
foreach (XmlNode xn in xnList)
{
Console.WriteLine("Sale: " + xn["Sale"].InnerText);
Console.WriteLine("Sale_Cnt: " + xn["Sale_Cnt"].InnerText);
Console.WriteLine("Payment_Type_ID: " + xn["Payment_Type_ID"].InnerText);
}
And it never went inside the foreach.
How do I get the values within PaymentMethod?
EDIT
I looked at the xmldocument's innertext and this is how it's displayed:
"<?xml version=\"1.0\" encoding=\"utf-8\"?><string xmlns=\"http://www.namespaceuri.com/Admin/ws\"><CardTrxSummary>\r\n <PaymentMethod>\r\n <Payment_Type_ID>VISA </Payment_Type_ID>\r\n <Authorization>0.0000</Authorization>\r\n <Capture>0.0000</Capture>\r\n <ForceCapture>0.0000</ForceCapture>\r\n <PostAuth>0.0000</PostAuth>\r\n <Return>0.0000</Return>\r\n <Sale>3419.2700</Sale>\r\n <Receipt>0.0000</Receipt>\r\n <RepeatSale>0.0000</RepeatSale>\r\n <Activate>0.0000</Activate>\r\n <Deactivate>0.0000</Deactivate>\r\n <Reload>0.0000</Reload>\r\n <Authorization_Cnt>0</Authorization_Cnt>\r\n <Capture_Cnt>0</Capture_Cnt>\r\n <ForceCapture_Cnt>0</ForceCapture_Cnt>\r\n <PostAuth_Cnt>0</PostAuth_Cnt>\r\n <Return_Cnt>0</Return_Cnt>\r\n <Sale_Cnt>13</Sale_Cnt>\r\n <Receipt_Cnt>0</Receipt_Cnt>\r\n <RepeatSale_Cnt>0</RepeatSale_Cnt>\r\n <Activate_Cnt>0</Activate_Cnt>\r\n <Deactivate_Cnt>0</Deactivate_Cnt>\r\n <Reload_Cnt>0</Reload_Cnt>\r\n <Cnt>13</Cnt>\r\n </PaymentMethod>\r\n</CardTrxSummary></string>"
Which, I assume, is part of my problem?
EDIT#2
This is what I ended up doing to get it to work. I'm sure there is a better way:
var tst2 = tst.InnerText.Replace("<", "<").Replace(">", ">").Replace("\r\n", string.Empty);
Console.WriteLine("Cnt: " + ReadXmlValue1(tst2, "Cnt"));
and my method to parse it:
private static void ReadXmlValue1(string xmlDocument)
{
XDocument xdoc = XDocument.Parse(xmlDocument);
//XNamespace ns = "http://www.namespaceuri.com/Admin/ws";
var payments = from p in xdoc.Descendants("PaymentMethod")
select new
{
Sale = (decimal)p.Element("Sale"),
SaleCount = (int)p.Element("Sale_Cnt"),
PaymentType = (string)p.Element("Payment_Type_ID")
};
Console.WriteLine("Count: " + payments.Count());
foreach (var payment in payments)
{
Console.WriteLine("Sale: " + payment.Sale);
Console.WriteLine("Sale_Cnt: " + payment.SaleCount);
Console.WriteLine("Payment_Type_ID: " + payment.PaymentType);
}
}
EDIT#3
This is how I'm creating the xmldocument:
/// <summary>
/// Get Data in xml format by url
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private static XmlDocument GetXmlDataFromUrl(string url)
{
//requesting the particular web page
var httpRequest = (HttpWebRequest)WebRequest.Create(url);
//geting the response from the request url
var response = (HttpWebResponse)httpRequest.GetResponse();
//create a stream to hold the contents of the response (in this case it is the contents of the XML file
var receiveStream = response.GetResponseStream();
//creating XML document
var mySourceDoc = new XmlDocument();
//load the file from the stream
if (receiveStream != null)
{
mySourceDoc.Load(receiveStream);
//close the stream
receiveStream.Close();
return mySourceDoc;
}
return null;
}
Upvotes: 0
Views: 1187
Reputation: 236218
You can use LINQ to XML to get list of strongly typed anonymous payment objects:
WebClient client = new WebClient();
string content = client.DownloadString(url);
XDocument xdoc = XDocument.Parse(content);
XNamespace ns = "http://www.namespaceuri.com/Admin/ws";
var payments = from p in xdoc.Descendants(ns + "PaymentMethod")
select new {
Sale = (decimal)p.Element(ns + "Sale"),
SaleCount = (int)p.Element(ns + "Sale_Cnt"),
PaymentType = (string)p.Element(ns + "Payment_Type_ID")
};
Keep in mind, that your xml has namespace declared, so you should provide it when specifying element names.
Usage:
foreach(var payment in payments)
{
Console.WriteLine("Sale: " + payment.Sale);
Console.WriteLine("Sale_Cnt: " + payment.SaleCount);
Console.WriteLine("Payment_Type_ID: " + payment.PaymentType);
}
Upvotes: 1
Reputation: 2378
XmlNode node = xmlDocument.SelectSingleNode("/string/CardTrxSummary/PaymentMethod");
Console.WriteLine("Sale: " + node.SelectSingleNode("Sale").InnerText);
Console.WriteLine("Sale_Cnt: " + node.SelectSingleNode("Sale_Cnt").InnerText);
Console.WriteLine("Payment_Type_ID: " + node.SelectSingleNode("Payment_Type_ID").InnerText);
or you can use getElementByTagName instead;
Console.WriteLine("Sale: " + xmlDocument.getElementByTagName("Sale").InnerText);
Console.WriteLine("Sale_Cnt: " + xmlDocument.getElementByTagName("Sale_Cnt").InnerText);
Console.WriteLine("Payment_Type_ID: " + xmlDocument.getElementByTagName("Payment_Type_ID").InnerText);
And just a note, the above 2 method is assuming that the tag will never return null.
If you want to handle possible null node, you can do something like this.
string text = xmlDocument.getElementByTagName("Sale") != null ? xmlDocument.getElementByTagName("Sale").InnerText : "unidentified";
The above line has the format like this:
var variable = condition ? A : B;
It's basically saying that if condition is true, variable equals A, otherwise variable equals B.
Upvotes: 0