Проблеми с Link 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>

Искам всеки контакт да го картографира върху обект Контакт. За да направя това, използвам този фрагмент от код:

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"), НЕ ПОЛУЧАВАМ НИЩО: Празен SET.

ОК, ти ми кажи: Използвай другия: ОК, ПРАВЯ ТАКА, нека използвам: from e in XRoot.Elements(), така или иначе получавам всички възли, ТОВА Е ПРАВИЛНО, НО ТУК ИДВА ДРУГИЯТ ПРОБЛЕМ: Когато казваш: select new Contact((string)e.Element("name"), (string)e.Element("email"), "1-1-1", null, null); Опитвам се да осъществя достъп до <name>, <email>... ТРЯБВА ДА ИЗПОЛЗВАЙТЕ .Element("име") И ТОВА СЪЩО НЕ РАБОТИ!!!!!!!!КАКВО ПО ДЯВОЛИТЕ Е ТОВА????????????? ИЗГЛЕЖДА, ЧЕ НЕ СЪВПАДА С ИМЕТО, КОЕТО МИНАВАМ Но как е възможно. Знам, че функцията 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