Запрос Linq на XML ничего не выбирает

#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>();