简体   繁体   English

从WebRequest解析xmldocument

[英]parsing an xmldocument from a webrequest

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. 名称中不能包含':'字符,十六进制值0x3A。

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. 而且它从来没有进入过foreach。

How do I get the values within PaymentMethod? 如何在PaymentMethod中获取值?

EDIT 编辑

I looked at the xmldocument's innertext and this is how it's displayed: 我看了xmldocument的内部文本,这是它的显示方式:

"<?xml version=\"1.0\" encoding=\"utf-8\"?><string xmlns=\"http://www.namespaceuri.com/Admin/ws\">&lt;CardTrxSummary&gt;\r\n  &lt;PaymentMethod&gt;\r\n    &lt;Payment_Type_ID&gt;VISA      &lt;/Payment_Type_ID&gt;\r\n    &lt;Authorization&gt;0.0000&lt;/Authorization&gt;\r\n    &lt;Capture&gt;0.0000&lt;/Capture&gt;\r\n    &lt;ForceCapture&gt;0.0000&lt;/ForceCapture&gt;\r\n    &lt;PostAuth&gt;0.0000&lt;/PostAuth&gt;\r\n    &lt;Return&gt;0.0000&lt;/Return&gt;\r\n    &lt;Sale&gt;3419.2700&lt;/Sale&gt;\r\n    &lt;Receipt&gt;0.0000&lt;/Receipt&gt;\r\n    &lt;RepeatSale&gt;0.0000&lt;/RepeatSale&gt;\r\n    &lt;Activate&gt;0.0000&lt;/Activate&gt;\r\n    &lt;Deactivate&gt;0.0000&lt;/Deactivate&gt;\r\n    &lt;Reload&gt;0.0000&lt;/Reload&gt;\r\n    &lt;Authorization_Cnt&gt;0&lt;/Authorization_Cnt&gt;\r\n    &lt;Capture_Cnt&gt;0&lt;/Capture_Cnt&gt;\r\n    &lt;ForceCapture_Cnt&gt;0&lt;/ForceCapture_Cnt&gt;\r\n    &lt;PostAuth_Cnt&gt;0&lt;/PostAuth_Cnt&gt;\r\n    &lt;Return_Cnt&gt;0&lt;/Return_Cnt&gt;\r\n    &lt;Sale_Cnt&gt;13&lt;/Sale_Cnt&gt;\r\n    &lt;Receipt_Cnt&gt;0&lt;/Receipt_Cnt&gt;\r\n    &lt;RepeatSale_Cnt&gt;0&lt;/RepeatSale_Cnt&gt;\r\n    &lt;Activate_Cnt&gt;0&lt;/Activate_Cnt&gt;\r\n    &lt;Deactivate_Cnt&gt;0&lt;/Deactivate_Cnt&gt;\r\n    &lt;Reload_Cnt&gt;0&lt;/Reload_Cnt&gt;\r\n    &lt;Cnt&gt;13&lt;/Cnt&gt;\r\n  &lt;/PaymentMethod&gt;\r\n&lt;/CardTrxSummary&gt;</string>"

Which, I assume, is part of my problem? 我认为这是我的问题的一部分?

EDIT#2 编辑#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("&lt;", "<").Replace("&gt;", ">").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 编辑#3

This is how I'm creating the xmldocument: 这就是我创建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;
}

You can use LINQ to XML to get list of strongly typed anonymous payment objects: 您可以使用LINQ to XML来获取强类型匿名支付对象的列表:

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. 请记住,您的xml已声明了名称空间,因此在指定元素名称时应提供它。

Usage: 用法:

foreach(var payment in payments)
{
   Console.WriteLine("Sale: " + payment.Sale);
   Console.WriteLine("Sale_Cnt: " + payment.SaleCount);
   Console.WriteLine("Payment_Type_ID: " + payment.PaymentType);
}
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; 或者您可以改用getElementByTagName;

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. 请注意,上述2种方法假定该标记永远不会返回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. 基本上是说,如果条件为真,则变量等于A,否则变量等于B。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM