2015-07-21 3 views
1

Я получаю некоторые XML-данные в виде строки из базы данных. Данные сохраняются как ntext в базе данных.Исключительное исключение ссылки - XDocument с использованием Element и XPath

Получение данных из базы данных не является проблемой. Проблема позже, когда я хочу обрабатывать данные в xml. Я загружаю строку в xDocument.

Я хочу сначала получить значение Владельца. Но я получаю исключение с нулевой ссылкой, а это значит, что я не пишу правильный Xpath, я предполагаю.

Запись "./Owner" не работает. Написание «/./Owner» не работает, я получаю исключение XML.

Я начал с XMLDocument, но думаю, что столкнулся с проблемой пространства имен. Началось чтение и похоже, что лучше использовать xDocument. Как вы также можете видеть по моему коду, я попытался получить значение «Владелец» двумя способами: оба сбой.

Мой XML выглядит как это:

<Container xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="DM"> 
<IsConsigned>false</IsConsigned> 
<LockState>Unlocked</LockState> 
<SourceType i:nil="true" /> 
<Id>04216194-4f62-47ee-ab21-c1053d01bf1e</Id> 
<Owner>IN</Owner> 
<Created>2012-08-21T09:29:10.528321+02:00</Created> 
</Container> 

И мой код:

 class Program 
{ 
    static SqlConnection conn = new SqlConnection(); 
    static XDocument xml = new XDocument(); 

    static void Main(string[] args) 
    { 
     using (conn) 
     { 
      conn.ConnectionString = Properties.Settings.Default.connectionString; 
      //connection.Open(); 
      conn.Open(); 
      SqlDataReader reader = GetDataFromDatabase(); 

      if (reader.HasRows) 
      { 

       while (reader.Read()) 
       { 
        string xmlFile = reader.GetSqlString(0).ToString(); 
        HandleData(xmlFile); 
       } 
      } 
      else 
      { 
       Console.WriteLine("No rows found."); 
      } 
      reader.Close(); 
     } 
    } 

    public static void HandleData(string xmlIn) 
    { 

     xml = XDocument.Parse(xmlIn); 
     XElement xmlElement = xml.Root; 
     string test1 = xml.Element("Owner").Value.ToString(); 
     string test = xmlElement.Element("Owner").Value.ToString(); 
    } 

    } 

ответ

2

Это была не проблема использования XmlDocument или XDocument. Ваш XML имеет пространство имен по умолчанию пространство имен объявляется без префикса, здесь:

xmlns="DM" 

контрастирует с тем, с префиксом i здесь: xmlns:i="http://www.w3.org/2001/XMLSchema-instance". Обратите внимание, что не только элемент, в котором объявлено пространство имен по умолчанию, находится в этом пространстве имен, но все элементы-потомки неявно наследуют пространство имен по умолчанию, если не указано иное (с использованием явного префикса пространства имен или локального пространства имен по умолчанию, указывающего на другое пространство имен uri).

Вы можете использовать комбинацию "XNamespace"+"element's local name", чтобы сформировать квалифицированное-имя для ссылки на элемент в пространстве имен, например:

var xmlIn = @"<Container xmlns:i='http://www.w3.org/2001/XMLSchema-instance' xmlns='DM'> 
<IsConsigned>false</IsConsigned> 
<LockState>Unlocked</LockState> 
<SourceType i:nil='true' /> 
<Id>04216194-4f62-47ee-ab21-c1053d01bf1e</Id> 
<Owner>IN</Owner> 
<Created>2012-08-21T09:29:10.528321+02:00</Created> 
</Container>"; 
var xml = XDocument.Parse(xmlIn); 
XNamespace d = "DM"; 
string owner = xml.Root.Element(d+"Owner").Value; 
Console.WriteLine(owner); 
string id = xml.Root.Element(d+"Id").Value; 
Console.WriteLine(id); 

Dotnetfiddle Demo

выход:

IN 
04216194-4f62-47ee-ab21-c1053d01bf1e 

Боковые ноты:

  • Element() не распознает выражение XPath, он принимает XName параметр вместо этого.
  • XElement.Value свойство строка уже, не нужно звонить ToString() на нем.
  • Аналогичный случай для справки, если вам нужно использовать XPath с XDocument позже: Use XPath with XML namespace
+0

Спасибо! Так оно и было. Я понимаю, что я кое-что читаю в отношении пространств имен. Как вы видите в моем первом посте, я столкнулся с проблемами пространства имен с XMLDocument, но не понял, как я мог его решить. С вашей помощью я все равно нахожусь на правильном пути. Подробнее о пространствах имен и префиксах читаю. Еще раз спасибо! – Dreas89

0

Пожалуйста, прочитайте больше о XPath в http://www.w3schools.com/xpath/default.asp.

Ваше решение здесь: https://dotnetfiddle.net/Aflm8t

+0

Как читать на Xpath помочь мне в этом вопросе более точно? Да, моя первая попытка получить правильное значение не работает, потому что я не пишу «Контейнер/Владелец». Просто тест, приведенный ниже, с помощью xml.root (контейнер, справа?), А затем переход к «Владелец» должен быть правильным Xpath, если я не ошибаюсь? Вы также в своем коде назначаете пространство имен, используемое в XML для экземпляра, я предполагаю? Где глюк, Пространство имён? Просто добавив «Использование XML.XPath», а затем xpath не работает. Поэтому ошибка должна быть где-то в другом месте. Я предполагаю, что так или иначе. – Dreas89

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