Проверьте, существует ли элемент при разборе XML
Я разбираю XML. Я обычно разбираю его так, как я показываю в приведенном ниже коде, что прямо. Проблема в том, что я не владею XML-анализом, и я не могу его изменить. Иногда нет элемента эскиза (нет тегов), и я получаю Exception
.
Есть ли способ сохранить эту простоту и проверить, существует ли элемент? Или мне нужно сначала получить список XElement
с LINQ, чтобы проверить его и заполнить только существующие свойства объекта?
void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
XDocument dataDoc = XDocument.Load(new StringReader(e.Result));
var listitems = from noticia in dataDoc.Descendants("Noticia")
select new News()
{
id = noticia.Element("IdNoticia").Value,
published = noticia.Element("Data").Value,
title = noticia.Element("Titol").Value,
subtitle = noticia.Element("Subtitol").Value,
thumbnail = noticia.Element("Thumbnail").Value
};
itemList.ItemsSource = listitems;
}
Ответы
Ответ 1
Создайте метод расширения следующим образом:
public static string TryGetElementValue(this XElement parentEl, string elementName, string defaultValue = null)
{
var foundEl = parentEl.Element(elementName);
if (foundEl != null)
{
return foundEl.Value;
}
return defaultValue;
}
измените свой код следующим образом:
select new News()
{
id = noticia.TryGetElementValue("IdNoticia"),
published = noticia.TryGetElementValue("Data"),
title = noticia.TryGetElementValue("Titol"),
subtitle = noticia.TryGetElementValue("Subtitol"),
thumbnail = noticia.TryGetElementValue("Thumbnail", "http://server/images/empty.png")
};
Этот подход позволяет сохранить чистый код с отключением проверки присутствия элемента. Это также позволяет вам определить значение по умолчанию, которое может быть полезно
Ответ 2
Вместо использования свойства Value
, если вы добавили в строку, вы просто получите нулевую ссылку:
void wc_DownloadStringCompleted(object sender,
DownloadStringCompletedEventArgs e)
{
XDocument dataDoc = XDocument.Load(new StringReader(e.Result));
var listitems = from noticia in dataDoc.Descendants("Noticia")
select new News()
{
id = (string) noticia.Element("IdNoticia"),
published = (string) noticia.Element("Data"),
title = (string) noticia.Element("Titol"),
subtitle = (string) noticia.Element("Subtitol"),
thumbnail = (string) noticia.Element("Thumbnail")
};
itemList.ItemsSource = listitems;
}
Это использует явное преобразование из XElement
в string
, которое обрабатывает нулевой ввод, возвращая нулевой вывод. То же самое верно для всех явных преобразований в XAttribute
и XElement
для типов с нулевым значением, включая типы значений с нулевым значением, такие как int?
- вам просто нужно быть осторожным, если вы используете вложенные элементы. Например:
string text = (string) foo.Element("outer").Element("inner");
даст нулевую ссылку, если inner
отсутствует, но все равно будет выдавать исключение, если отсутствует outer
.
Если вы хотите "значение по умолчанию", вы можете использовать оператор нулевой коалесценции (??
):
string text = (string) foo.Element("Text") ?? "Default value";
Ответ 3
Вы можете просто использовать System.Xml.Serialization.XmlSerializer
для десериализации его из xml в объект. Тогда, если элемент не существует, свойство объекта просто получит его значение по умолчанию.
Посмотрите здесь: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx
или новый путь
https://docs.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlserializer
Ответ 4
Вы можете использовать следующий код:
string content = item.Element("Content") == null ? "" : item.Element("Content").Value;