2009-10-20 3 views
1

Я хочу найти раздел xml на основе критериев, поэтому я использую linq для XML. К сожалению, результат всегда равен нулю, поэтому я думаю, что я сделал что-то неправильно. Ниже приведен пример XML-анализа.Поиск определенного элемента XML на основе идентификатора с использованием Linq

<Stuff> 
<ItemsA /> 
<ItemsB /> 
<ItemsC> 
    <Item xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Stuff"> 
    <Id>4bd7b5ac-cb29-4d34-97be-deaebe4a5186</Id> 
    <Children> 
    <Item> 
     <Id>22e3ef6b-4321-40c3-9237-196ba527e9ad </Id> 
     <Name>SomeName</Name> 
    </Item> 
    </Children> 
    <Description>SomeText</Description> 
    <Name>NewName</Name> 
</Item>  

Я смотрю на раздел «ItemsC», где может быть несколько «Пункт» блоки XML (только один показан в этом примере). Я хочу получить элемент на основе его «Id», который имеет идентификатор «4bd7b5ac-cb29-4d34-97be-deaebe4a5186» в приведенном выше примере.

Код я использовал показано ниже:

XElement данные = XElement.Parse (GetFile());

var pbp = (from b in data.Descendants("Item") 
      where b.Element("Id").Value == "4bd7b5ac-cb29-4d34-97be-deaebe4a5186" 
      select b.Element("Id").Parent).FirstOrDefault(); 

pbp всегда возвращается как null. Может ли кто-нибудь помочь мне создать правильное выражение linq.

ответ

0

Да - вы просто не хватает пространства имен:

string desiredId = "4bd7b5ac-cb29-4d34-97be-deaebe4a5186"; 
XNamespace ns = "http://schemas.datacontract.org/2004/07/Stuff"; 
var pbp = (from b in data.Descendants(ns + "Item") 
      where b.Element(ns + "Id").Value == desiredId 
      select b).FirstOrDefault(); 

Обратите внимание, что я упростил b.Element("Id").Parent просто b - если вы только собираетесь вниз по дереву, а затем снова, вы можете остатся где вы :)

Это предполагает дальнейшее упрощение использовать точечную нотацию:

string desiredId = "4bd7b5ac-cb29-4d34-97be-deaebe4a5186"; 
XNamespace ns = "http://schemas.datacontract.org/2004/07/Stuff"; 
var pbp = data.Descendants(ns + "Item") 
       .Where(b => b.Element(ns + "Id").Value == desiredId) 
       .FirstOrDefault(); 

Если есть шанс, что элемент не будет ВГ е элемент «Id», то вы можете бросить в строку вместо:

string desiredId = "4bd7b5ac-cb29-4d34-97be-deaebe4a5186"; 
XNamespace ns = "http://schemas.datacontract.org/2004/07/Stuff"; 
var pbp = data.Descendants(ns + "Item") 
       .Where(b => (string) b.Element(ns + "Id") == desiredId) 
       .FirstOrDefault(); 

Это позволяет избежать возможного NullReferenceException.

+0

Спасибо, что изменение в настоящее время работает. Время для меня, чтобы сделать еще немного чтения на Linq :) – Retrocoder

0

Вам просто нужно добавить пространство имен в запросе, то есть

XNamespace ns = "http://schemas.datacontract.org/2004/07/Stuff"; 

var pbp = 
    (from b in data.Descendants(ns + "Item") 
    where b.Element(ns + "Id").Value == "4bd7b5ac-cb29-4d34-97be-deaebe4a5186" 
    select b.Element(ns + "Id").Parent).FirstOrDefault(); 
Смежные вопросы