#c# #xml #linq-to-xml
#c# #xml #linq-to-xml
Вопрос:
У меня довольно сложный XML-документ
<ItemSearchResponse xmlns="-------">
<OperationRequest>
<HTTPHeaders>
</HTTPHeaders>
<RequestId>0S57WGDPNC7T8HNBV76K</RequestId>
<Arguments>
</Arguments>
<RequestProcessingTime>0.441776990890503</RequestProcessingTime>
</OperationRequest>
<Items>
<Request>
<ItemSearchRequest>
</ItemSearchRequest>
</Request>
<TotalResults>1020</TotalResults>
<TotalPages>102</TotalPages>
<Item>
<ASIN>B004WL0L9S</ASIN>
<SalesRank>1</SalesRank>
<ItemAttributes>
<Manufacturer>Georgia Pacific Consumer Products LP (Cut-Sheet Paper)</Manufacturer>
<Title>GP Copy amp;amp; Print Paper, 8.5 x 11 Inches Letter Size, 92 Bright White, 20 Lb, Ream of 500 Sheets (998067R)</Title>
<ItemAttributes>
</Item>
<Items>
Я запускаю этот запрос над ним, и он возвращает список нулей:
XDocument doc = XDocument.Load(url);
List<Item> Items = (from c in doc.Elements("Item")
select new Item
{
Title = c.Element("Title").Value
SaleRank = c.Element("SaleRank").Value
ASIN = c.Element("ASIN").Value
}).ToList<Item>();
Я действительно новичок в XLinq, но, согласно документации, это должно работать.
Ответ №1:
Прежде всего, у вас недопустимый xml. Вот пример того, как это должно выглядеть:
<ItemSearchResponse >
<OperationRequest>
<HTTPHeaders> </HTTPHeaders>
<RequestId>0S57WGDPNC7T8HNBV76K</RequestId>
<Arguments> </Arguments>
<RequestProcessingTime>0.441776990890503</RequestProcessingTime>
</OperationRequest>
<Items>
<Request>
<ItemSearchRequest> </ItemSearchRequest>
</Request>
<TotalResults>1020</TotalResults>
<TotalPages>102</TotalPages>
<Item>
<ASIN>B004WL0L9S</ASIN>
<SalesRank>1</SalesRank>
<ItemAttributes>
<Manufacturer>Georgia Pacific Consumer Products LP (Cut-Sheet Paper)</Manufacturer>
<Title>GP Copy amp;amp; Print Paper, 8.5 x 11 Inches Letter Size, 92 Bright White, 20 Lb, Ream of 500 Sheets (998067R)</Title>
</ItemAttributes>
</Item>
</Items>
</ItemSearchResponse>
И этот код работает с ним:
var Items = (from c in doc.Root.Element("Items").Elements("Item")
select new Item()
{
Title = c.Element("ItemAttributes").Element("Title").Value,
SaleRank = c.Element("SalesRank").Value,
ASIN = c.Element("ASIN").Value
}).ToList();
или с Descendants
:
var Items = (from c in doc.Root.Descendants("Item")
select new
{
Title = c.Element("ItemAttributes").Element("Title").Value,
SaleRank = c.Element("SalesRank").Value,
ASIN = c.Element("ASIN").Value
}).ToList();
Комментарии:
1. Я пытаюсь использовать его против веб-ответа, который мне возвращают. Кроме отсутствия этого закрывающего тега, это его копия и вставленная версия.
Ответ №2:
Проблема заключается в вашем использовании .Elements(XName)
, которое, как вам кажется, вы предполагаете, является рекурсивным. Это не так, он проверяет только прямые дочерние элементы целевого объекта (в данном случае документ).
Я полагаю, что функция, которую вы ищете .Descendants(XName)
, будет выглядеть рекурсивно, но имейте в виду, что это не очень быстро в массивных XML-документах.
Ответ №3:
Проблема заключается в разнице между элементами и потомками
var items = (from c in doc.Descendants("Item")
select new Item
{
Title = c.Element("ItemAttributes").Element("Title").Value,
SaleRank = c.Element("SalesRank").Value,
ASIN = c.Element("ASIN").Value
}).ToList<Item>();
Элементы список элементов Xml непосредственно под текущим элементом (т. Е. Только 1 уровень в глубину). Потомки извлекут все элементы.
Основываясь на вашем Xml и вашем запросе, я показал использование потомка и элемента. В начальном цикле используются Descendants() , но доступ к Title используется для вызовов chained Element() .
Я попытался запустить код, и я предполагаю, что xmlns был удален для публикации, но в вашем фактическом коде есть реальное пространство имен. Если нет, возможно, это проблема, которую вам нужно решить в первую очередь.
Ответ №4:
Оказывается, мне нужно добавить пространство имен для запроса.
XNamespace ns = NAMESPACE;
var items = (from c in doc.Descendants(ns "Item")
select new Item
{
Title = c.Element(ns "ItemAttributes").Element(ns "Title").Value,
SalesRank = c.Element(ns "SalesRank").Value,
ASIN = c.Element(ns "ASIN").Value
}).ToList<Item>();