2013-06-15 2 views
0

Я пытаюсь сделать XML-парсер для XML-документов, где есть некоторые необязательные атрибуты в узлах, и я ищу элегантный способ, как решить проблему с помощью «Ссылка на объект не установлен в экземпляр ". Я прочитал this тему, которая очень похожа и следующий код казался очень перспективным:Подстановка несуществующего атрибута XML со значением по умолчанию

string text = (string) foo.Element("Text") ?? "Default value"; 

Однако, когда я попытался осуществить это, «ссылка на объект не указывает на экземпляр» все еще произошло, и поэтому я Я ищу другое решение. Вот часть моего отчаянного усилия.

XML файл 1:

... 
<Message id ="1" appendix = "abc" ></Message> 
... 

XML файл 2:

... 
<Message id ="2" ></Message> 
... 

Мой анализатор (вызывается в цикле для каждого файла в папке):

public MyNode Parse(string file) 
{ 
    XmlDocument xDoc = new XmlDocument(); 
    xDoc.Load(file); 

    MyNode node = new MyNode(); 
    node.messageID = (string)xDoc.GetElementsByTagName("Message")[0].Attributes["id"].Value ?? "NULL"; 
    node.appendix = (string)xDoc.GetElementsByTagName("Message")[0].Attributes["appendix"].Value ?? "NULL"; 

    return node; 
} 

Могли бы вы выручи меня?

+0

Что говорит отладчик null? –

+0

["appendix"] Атрибут ... Я получаю исключение ссылки Null: ссылка объекта не установлена ​​в экземпляр объекта. Или, может быть, значение атрибута, я не уверен. – Storm

ответ

1

К сожалению, это работает только, если Value является null, не если фактическая XAttribute является null.

Вы должны сделать что-то вроде этого:

XAttribute temp = xDoc.GetElementsByTagName("Message")[0].Attributes["appendix"]; 
if (temp == null) 
{ 
    node.appendix = temp.Value; 
} 
else 
{ 
    node.appendix = "NULL"; 
} 
+0

Ну, это печальное открытие ... в любом случае, большое спасибо за ваш ответ. – Storm

+0

может выглядеть немного лучше с 'node.appendix = temp == null? «NULL»: temp.value; ' –

1

После LINQ для запроса XML возвратит MyNode объекта, заполненные значения идентификатора сообщения и приложение атрибутов. Если какой-то атрибут не найден, то defalult значения «NULL» используются:

var xDoc = XDocument.Load(file); 
var node = xDoc.Descendants("Message") 
       .Select(m => new MyNode { 
        messageID = (string)m.Attribute("id") ?? "NULL", 
        appendix = (string)m.Attribute("appendix") ?? "NULL" 
       }).FirstOrDefault(); 

Если нет Message элементов в XML-документе, то null будет возвращено.

BTW, когда вы используете LINQ to XML, лучше использовать литейный узел до (string), чем доступ к его Value. Потому что если узел не найден в документе, то вы получите NullReferenceException, если вы попытаетесь получить Value имущество null. Но когда вы набрасываете узел на string, вы просто получаете значение null вместо исключения. Это позволяет вам указать значение по умолчанию с помощью оператора с нулевым коалесцированием.

+0

Большое спасибо за ваш исчерпывающий ответ. Теперь я немного лучше разбираюсь в процессе синтаксического анализа. Однако ответ моего коллеги был легче реализовать в моем коде (мне пришлось перекодировать меньше строк), поэтому я принял его ответ. – Storm

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