2010-08-11 2 views
5

Я действительно не хотел обращаться за помощью, поскольку я знаю, что в конечном итоге это выясню, но я потратил слишком много времени, если у документа были родительские теги или лучшая структура, это будет кусок пирога. К сожалению, я загружаю документ, и я просто не могу понять, как получить данные.Выбор XElement из XDocument

Я пробовал несколько запросов linq и foreach, используя XElement в качестве итератора. Во всяком случае, вот пример структуры.

<ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:yahoo:srch" xsi:schemaLocation="urn:yahoo:srch http://api.search.yahoo.com/SiteExplorerService/V1/InlinkDataResponse.xsd" totalResultsAvailable="247930100" firstResultPosition="99" totalResultsReturned="100"> 
<Result> 
    <Title>Adobe - Adobe Reader</Title> 
    <Url>http://get.adobe.com/fr/reader/</Url> 
    <ClickUrl>http://get.adobe.com/fr/reader/</ClickUrl> 
    </Result> 
<Result> 
    <Title>Religious Tolerance</Title> 
    <Url>http://www.religioustolerance.org/</Url> 
    <ClickUrl>http://www.religioustolerance.org/</ClickUrl> 
    </Result> 
<Result> 
    <Title>Applications Internet riches (RIA) | Adobe Flash Player</Title> 
    <Url>http://www.adobe.com/fr/products/flashplayer/</Url> 
    <ClickUrl>http://www.adobe.com/fr/products/flashplayer/</ClickUrl> 
    </Result> 
<Result> 
    <Title>photo management software | Adobe Photoshop Lightroom 3</Title> 
    <Url>http://www.adobe.com/products/photoshoplightroom/</Url> 
    <ClickUrl>http://www.adobe.com/products/photoshoplightroom/</ClickUrl> 
    </Result> 
<Result> 
    <Title>Battle for Wesnoth</Title> 
    <Url>http://www.wesnoth.org/</Url> 
    <ClickUrl>http://www.wesnoth.org/</ClickUrl> 
    </Result> 
</ResultSet> 

Приведен пример последнего фрагмента.

foreach (XElement ele in xDoc.Descendants("ResultSet").Elements("Result")) 
       { 
        CollectedUris.Add(ele.Element("Url").Value); 
       } 

ответ

8

Вам нужно добавить XNamespace:

XNamespace ns = "urn:yahoo:srch"; 

var query = xDoc.Root.Descendants(ns + "Result").Elements(ns + "Url") 

foreach(XElement e in query) 
{ 
    CollectedUris.Add(e.Value); 
} 

Edit:
Решение LINQ для бонусных баллов:

xDoc.Root.Descendants(ns + "Result") 
    .Elements(ns + "Url") 
    .Select(x => x.Value).ToList() 
    .ForEach(CollectedUris.Add); 
+0

А я понятия не имел об пространствах имен, конечно, не решил бы это без помощи кому-то, спасибо! – Ash

2

Я предполагаю, что вы хотите все<Url> элементы в документе. Если это так, то ваша петля почти там. Вы захотите сделать следующее.

using System.Xml.Linq; 

foreach (XElement ele in xDoc.Root.Descendants("Result").Descendants("Url") 
{ 
    CollectedUris.Add(ele.Value); 
} 

Root получает вам ссылку на корневой элемент, и оператор, следующий Descendants возвращает только <Result> узлы. Последняя инструкция Descendants дополнительно ограничивает перечислитель узла <Result> только для возврата элементов <Url>.

+0

Спасибо за пример, я обновил XML структура, поскольку она не была удобочитаема. В любом случае странно метод Add в цикле не запускается (на нем есть точка останова). Не могли бы вы проверить структуру и убедиться, что я не делаю ничего глупого. Еще раз спасибо – Ash

+1

@Ash - см. Мое решение. Стив прав, если нет пространства имен, но для вашего примера требуется менеджер пространства имен. –

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