2013-02-11 3 views
2

Я уверен, что это простой вопрос, но у меня есть реальное затенение и вы не можете найти решение.Получение значения кода ошибки из xml-файла

У меня есть очень простой XML, который выглядит как:

<xml-header> 
    <error code="40" message="errorMessage" /> 
    </xml-header> 

И мне нужно, чтобы получить значение «40» от нее. Итак, на мой взгляд, это означает: получить значение из атрибута «код» элемента «ошибка». (Я прав?)

return (from node in xdoc.Descendants() select node.Element("error").Attribute("code").Value).First(); 

И это не работает. Какое правильное выражение?


[обновление]

К сожалению все, проблема была с XNamespace.

Так должно быть: xdoc.Descendants(Constants.xNamespace)даже был этот в классе констант, aarrgh.

+0

«не работает» == У вас есть исключения? или результат отличается от того, что вы ожидали? –

ответ

3

Выбор Потомок ошибка элементов. Также следует избегать использования значений свойств, если вы не хотите, чтобы получить исключение, если нет такого атрибута в элементе:

(from node in xdoc.Descendants("error") 
select (int)node.Attribute("code")) 
.First(); 

Вы также можете использовать метод синтаксис:

xdoc.Descendants("error") 
    .Select(e => (int)e.Attribute("code")) 
    .First() 

Имейте в виду, - Сначала будет генерироваться исключение, если последовательность не содержит элементов. Если вы хотите избежать этой ошибки, используйте вместо этого FirstOrDefault. Если существует пространство имен, то используйте его при выборе элементов:

XNamespace ns = "http://someAdress"; 
xdoc.Descendants(ns + "error") 
+0

Да, я понял. И теперь у меня есть «последовательность не содержит элементов». – Olter

+0

@Olter thats то, что я написал в 'Keep in mind' part :) Похоже, у вас нет элементов' error' в вашем xml. Вы уверены, что нет * пространства имен * определено? –

+0

Черт побери! Как я пропустил это?И, самое глупое, что я написал это пространство имен в вопросе обновления, но по какой-то причине оно не было напечатано. Благодарю. – Olter

1

Попробуйте что-то вроде этого (все обработки ошибок опущена!):

using System; 
using System.IO; 
using System.Xml.Linq; 
using System.Xml.XPath; 

namespace Demo 
{ 
    public static class Program 
    { 
     private static void Main(string[] args) 
     { 
      string xml = "<xml-header><error code=\"40\" message=\"errorMessage\" /></xml-header>"; 

      var element = XElement.Load(new StringReader(xml)); 
      var errorElement = element.XPathSelectElement("error"); 
      string code = errorElement.Attribute("code").Value; 

      Console.WriteLine(code); // Prints 40 
     } 
    } 
} 

Или, используя XDocument и избежать расширения:

using System; 
using System.IO; 
using System.Xml.Linq; 

namespace Demo 
{ 
    public static class Program 
    { 
     private static void Main(string[] args) 
     { 
      string xml = "<xml-header><error code=\"40\" message=\"errorMessage\" /></xml-header>"; 

      var doc = XDocument.Load(new StringReader(xml)); 

      var errorElement = doc.Element("xml-header").Element("error"); 
      string code = errorElement.Attribute("code").Value; 

      Console.WriteLine(code); // Prints 40 
     } 
    } 
} 
+0

Я работаю с Windows-телефоном, и кажется, что в его рамках нет метода _XPathSelectElement_. И мне нужно решение для объекта XDocument, не хотите, чтобы его/его анализировать из строки. – Olter

+0

Я приложил к моему ответу версию, которая работает с XDocument и избегает методов расширения. –

1

У вас уже есть error элемент потомков. Попробуйте это:

return xdoc.Descendants().Select(n => n.Attribute("code").Value).First(); 

или это, если вам нравится стиль запроса:

return (from node in xdoc.Descendants() select node.Attribute("code").Value).First(); 
+0

На самом деле, у меня есть исключение NullReferenceException как в моем собственном выражении, так и в вашем. – Olter

+0

@Olter Посмотрите на [это] (https://compilr.com/hamlet/test5/main.cs). В чем проблема с этим кодом? –

Смежные вопросы