简体   繁体   English

Linq to XML查询未选择任何内容

[英]Linq to XML Query not picking anything

I have a rather complex XML document 我有一个相当复杂的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; Print Paper, 8.5 x 11 Inches Letter Size, 92 Bright White, 20    Lb, Ream of 500 Sheets (998067R)</Title>
      <ItemAttributes>
    </Item>
  <Items>

I run this query over it and it returns of list of zero: 我对它运行此查询,并返回零列表:

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

I am really new to XLinq but according to the documentation that should work. 我真的是XLinq的新手,但是根据应该可以使用的文档。

First of all you have not valid xml. 首先,您没有有效的xml。 Here is example how it should looks: 这是示例应如何看起来:

<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; Print Paper, 8.5 x 11 Inches Letter Size, 92 Bright White, 20 Lb, Ream of 500 Sheets (998067R)</Title>
            </ItemAttributes>
        </Item>
    </Items>
</ItemSearchResponse>

And this code works with it: 此代码适用于:

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

or with Descendants : 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();

The problem lies in your use of .Elements(XName) which it seems you're assuming is recursive. 问题在于您使用的.Elements(XName)似乎是递归的。 It is not, It only inspects direct children of the target (in this case the document). 不是,它仅检查目标的直接子对象(在这种情况下为文档)。

I believe the function you're looking for is .Descendants(XName) which will look recursively, but be warned this is not very fast on massive XML docs. 我相信您要查找的函数是.Descendants(XName) ,它将以递归方式查找,但是请注意,在大型XML文档中,这并不是很快。

The problem is the difference between Elements and Descendants 问题是元素和后代之间的区别

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

Elements a list of Xml Elements directly underneath the current Element (ie only 1 level deep). 元素在当前元素正下方的Xml元素列表(即仅1级深)。 Descendants will retrieve all elements. 后代将检索所有元素。

Based on your Xml and your query, I showed the use of Descendant and Element. 根据您的Xml和查询,我展示了Descendant和Element的用法。 The initial loop uses Descendants(), but access to Title uses to chained Element() calls. 初始循环使用Descendants(),但对Title的访问用于链接Element()调用。

I tried running the code, and I'm assuming the xmlns was removed for posting, but your actual code has a real namespace in it. 我尝试运行代码,并假设xmlns被删除以进行发布,但是您的实际代码中包含真实的名称空间。 If not, that maybe a problem you need to resolve first. 如果不是,那可能是您首先需要解决的问题。

Turns out I need to add the namespace to query. 原来我需要添加名称空间进行查询。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM