0

我正在花时间解析这个布局:

<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>

我正在尝试使用此代码来获得特定结果:

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();
}

在这一点上,它给了我这个信息:

':' 字符,十六进制值 0x3A,不能包含在名称中。

我试过这样:

  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);
  }

它从来没有进入过foreach。

如何获取 PaymentMethod 中的值?

编辑

我查看了 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>"

我认为哪个是我的问题的一部分?

编辑#2

这就是我最终为了让它工作而做的事情。我确信有更好的方法:

  var tst2 = tst.InnerText.Replace("&lt;", "<").Replace("&gt;", ">").Replace("\r\n", string.Empty);
  Console.WriteLine("Cnt: " + ReadXmlValue1(tst2, "Cnt"));

以及我的解析方法:

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);
  }

}

编辑#3

这就是我创建 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;
}
4

2 回答 2

1

您可以使用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")
                };

请记住,您的 xml 已声明命名空间,因此您应该在指定元素名称时提供它。

用法:

foreach(var payment in payments)
{
   Console.WriteLine("Sale: " + payment.Sale);
   Console.WriteLine("Sale_Cnt: " + payment.SaleCount);
   Console.WriteLine("Payment_Type_ID: " + payment.PaymentType);
}
于 2013-07-31T17:03:09.690 回答
0
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);

或者您可以改用 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);

请注意,上述 2 方法是假设标签永远不会返回 null。

如果你想处理可能的空节点,你可以做这样的事情。

string text = xmlDocument.getElementByTagName("Sale") != null ? xmlDocument.getElementByTagName("Sale").InnerText : "unidentified";

上面的行具有如下格式:

var variable = condition ? A : B;

基本上是说如果条件为真,则变量等于A,否则变量等于B。

于 2013-07-31T16:50:37.720 回答