2013-07-31 4 views
0

У меня щеколда время разбора этот макет:разборе XmlDocument от WebRequest

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

И он никогда не вошел в Еогеасп.

Как получить значения в PaymentMethod?

EDIT

Я смотрел на InnerText в 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>" 

Что, я полагаю, это часть моей проблемы?

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

} 

EDIT # 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; 
} 
+0

Попробуйте 'версию XDocument' без пространств имен (' xdoc.Descendants ("PAYMENTMETHOD") '). Я думаю, вам также нужно будет изменить свой выбор, поскольку ни один из элементов не имеет атрибута 'cnt'. –

+0

Я изменю это и посмотрю, что произойдет, но этот существует: Вы имеете в виду дело? – ErocM

+0

'Cnt' является ** именем ** этого элемента, а не атрибутом. –

ответ

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

Я пробовал это, и payment.count равен 0. Я не получаю никакого удара по этому вопросу. – ErocM

+0

@ErocM, если вы разбираете строку xml, используйте метод 'XDocument.Parse (xml)' для создания документа. В противном случае убедитесь, что вы загружаете правильный файл. –

+0

Я закончил использовать это, но я уверен, что есть лучший способ. См. Мое второе редактирование. Можете ли вы проверить это и сказать мне, есть ли лучший способ? – ErocM

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; 

Это в основном говорят, что если условие истинно, то переменная равна А, в противном случае переменная равна B.

+0

Я подключил код точно так же, как он, в свой собственный метод, и я получаю «Ссылка на объект не установлена ​​в экземпляр объекта». Узел был нулевым. – ErocM

+0

Это означает, что узел, которого вы ищете, не существует, поэтому null. В какой строке вы получаете ошибку? – sora0419

+0

и извините, была опечатка, я только что исправил ее. – sora0419