Проблемы Linq To Xml с использованием метода XElement Elements (XName)

У меня проблема с использованием Linq To Xml.

Простой код. У меня есть этот XML:

<?xml version="1.0" encoding="utf-8" ?>
<data xmlns="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/directory file.xsd">
<contact>
 <name>aaa</name>
 <email>[email protected]</email>
 <birthdate>2002-09-22</birthdate>
 <telephone>000:000000</telephone>
 <description>Description for this contact</description>
</contact>
<contact>
 <name>sss</name>
 <email>[email protected]</email>
 <birthdate>2002-09-22</birthdate>
 <telephone>000:000000</telephone>
 <description>Description for this contact</description>
</contact>
<contact>
 <name>bbb</name>
 <email>[email protected]</email>
 <birthdate>2002-09-22</birthdate>
 <telephone>000:000000</telephone>
 <description>Description for this contact</description>
</contact>
<contact>
 <name>ccc</name>
 <email>[email protected]</email>
 <birthdate>2002-09-22</birthdate>
 <telephone>000:000000</telephone>
 <description>Description for this contact</description>
</contact>

Я хочу, чтобы каждый контакт отображал его на объекте Contact. Для этого я использую этот фрагмент кода:

XDocument XDoc = XDocument.Load(System.Web.HttpRuntime.AppDomainAppPath + this.filesource);
XElement XRoot = XDoc.Root;
//XElement XEl = XElement.Load(this.filesource);
var results = from e in XRoot.Elements("contact") 
 select new Contact((string)e.Element("name"), (string)e.Element("email"), "1-1-1", null, null);
List<Contact> cntcts = new List<Contact>();
foreach (Contact cntct in results) {
 cntcts.Add(cntct);
}
Contact[] c = cntcts.ToArray();
// Encapsulating element
Elements<Contact> final = new Elements<Contact>(c);

Хорошо, просто не обращайте внимания на все это: сосредоточьтесь на этом:

Когда я получаю корневой узел, все в порядке, я получаю его правильно.

Когда я использую директиву select, я пытаюсь заставить каждый узел сказать: from e in

XRoot.Elements("contact")

Хорошо, вот проблема: если я использую: from e в XRoot.Elements(), я получаю все контактные узлы, но если я использую: from e в XRoot.Elements("contact"), Я НИЧЕГО НЕ ПОЛУЧАЮ: пустой НАБОР.

ОК, вы говорите мне: Используйте другой: ОК, Я ДЕЛАЮ ТАК, давайте использовать: from e in XRoot.Elements(), я все равно получаю все узлы, ЭТО ПРАВИЛЬНО, НО ЗДЕСЬ ВОЗНИКАЕТ ДРУГАЯ ПРОБЛЕМА: Говоря: select new Contact((string)e.Element("name"), (string)e.Element("email"), "1-1-1", null, null); Я пытаюсь получить доступ к <name>, <email>... Я ДОЛЖЕН ИСПОЛЬЗУЙТЕ .Element("name") И ЭТО ТОЖЕ НЕ РАБОТАЕТ!!!!!!!!ЧТО ЭТО ЗА ХЕРНЯ????????????? КАЖЕТСЯ, ЧТО Я НЕ СООТВЕТСТВУЮ ИМЯ, КОТОРОЕ Я ПЕРЕДАЮ Но как это возможно. Я знаю, что функция Elements() принимает перегруженный один аргумент, который является XName, который отображается в строку. Пожалуйста, учтите, что код, который я написал, взят из примера. Он должен работать.


person Dorian McHensie    schedule 02.05.2010    source источник
comment
Добро пожаловать в Stackoverflow. Один совет: если вы публикуете фрагменты кода или фрагменты XML, пожалуйста, выделите эти строки и нажмите кнопку кода (101 010) на панели инструментов редактора, чтобы правильно отформатировать их. Ваш пост станет намного красивее и читабельнее!   -  person marc_s    schedule 02.05.2010


Ответы (2)


Довольно просто: в игре есть пространство имен XML, которое вы игнорируете:

<data xmlns="http://www.example.com"  
      **************************

Вам нужно добавить это в свои запросы Linq-to-XML!

Что-то типа:

XNamespace ns = "http://www.example.com";

а потом

XRoot.Elements(ns + "contact") 

и, конечно, также используйте пространство имен XML при доступе к дочерним элементам:

var results = from e in XRoot.Elements("contact") 
              select new Contact(e.Element(ns + "name").Value, 
                                 e.Element(ns + "email").Value, 
                                 "1-1-1", null, null);

Это должно помочь. См. документацию MSDN по Работа с пространствами имен XML для более подробной информации.

person marc_s    schedule 02.05.2010
comment
Это, пожалуй, единственная моя жалоба на API linq2xml. Большинство программ, над которыми я работал, не интересуется пространством имен, но для его обработки в любом случае необходим код. - person Frank Schwieterman; 02.05.2010
comment
@Frank: но что хорошего в пространствах имен (разработанных специально для устранения неоднозначности элементов с одинаковыми именами), когда ваш API нагло их игнорирует ?? Для меня это не имеет большого смысла, на самом деле.... - person marc_s; 02.05.2010
comment
ДЕЙСТВИТЕЛЬНО... Я ПОПРОБУЮ ЭТО СЕЙЧАС, В любом случае, спасибо, спасибо, это невероятно, вы так быстро ответили мне.... Спасибо на самом деле, я дам вам знать, как дела... Просто нужно попробовать :) - person Dorian McHensie; 02.05.2010
comment
ОК, ЭТО РАБОТАЕТ... БОЛЬШОЕ СПАСИБО. Я действительно не сосредоточился на пространствах имен :) Большое спасибо! - person Dorian McHensie; 02.05.2010
comment
Пространства имен полезны в XML, но мне редко приходится читать из разных пространств имен. Необходимость переопределять пространство имен постоянно кажется излишним. - person Frank Schwieterman; 03.05.2010
comment
Вы можете игнорировать пространства имен, если хотите: XRoot.Elements().Where(e => e.Name.LocalName == contact) - person Stephen Oberauer; 14.09.2011

Для меня я решил это так, потому что у меня не было пространства имен в моем XML:

xmldoc.Root.Elements("contact");

Я забыл использовать метод "Root".

person Bruno Bieri    schedule 20.11.2015