简体   繁体   English

使用XDocument.Load加载XML的后代

[英]Loading Descendants of XML using XDocument.Load

I am attempting to use XDocument.Load to access some latitude and longitude figures. 我正在尝试使用XDocument.Load访问一些经度和纬度数据。 Here is the example XML document; 这是示例XML文档。

<?xml version="1.0" encoding="utf-8"?>
<Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1">
  <Copyright>Copyright © 2016 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.</Copyright>
  <BrandLogoUri>http://dev.virtualearth.net/Branding/logo_powered_by.png</BrandLogoUri>
  <StatusCode>200</StatusCode>
  <StatusDescription>OK</StatusDescription>
  <AuthenticationResultCode>ValidCredentials</AuthenticationResultCode>
  <TraceId>31a206847f9341d28689e0e7185e163d|DB40051719|7.7.0.0|DB4SCH010061262</TraceId>
  <ResourceSets>
    <ResourceSet>
      <EstimatedTotal>1</EstimatedTotal>
      <Resources>
        <Location>
          <Name>SW1A 1AA, London, London, United Kingdom</Name>
          <Point>
            <Latitude>51.501018524169922</Latitude>
            <Longitude>-0.14159967005252838</Longitude>
          </Point>
          <BoundingBox>
            <SouthLatitude>51.497155806599245</SouthLatitude>
            <WestLongitude>-0.14987251765942367</WestLongitude>
            <NorthLatitude>51.5048812417406</NorthLatitude>
            <EastLongitude>-0.1333268224456331</EastLongitude>
          </BoundingBox>
          <EntityType>Postcode1</EntityType>
          <Address>
            <AdminDistrict>England</AdminDistrict>
            <AdminDistrict2>London</AdminDistrict2>
            <CountryRegion>United Kingdom</CountryRegion>
            <FormattedAddress>SW1A 1AA, London, London, United Kingdom</FormattedAddress>
            <Locality>London</Locality>
            <PostalCode>SW1A 1AA</PostalCode>
          </Address>
          <Confidence>High</Confidence>
          <MatchCode>Good</MatchCode>
          <GeocodePoint>
            <Latitude>51.501018524169922</Latitude>
            <Longitude>-0.14159967005252838</Longitude>
            <CalculationMethod>Rooftop</CalculationMethod>
            <UsageType>Display</UsageType>
          </GeocodePoint>
        </Location>
      </Resources>
    </ResourceSet>
  </ResourceSets>
</Response>

And here is the code I am using attempting to access latitude and longitude; 这是我尝试访问纬度和经度的代码;

    string latitude = XDocument.Load(@"test.xml").Root
                                            .Descendants("ResourceSets")
                                            .Descendants("ResourceSet")
                                            .Descendants("Resources")
                                            .Descendants("Location")
                                            .Descendants("GeocodePoint")
                                            .Select(element => element.Attribute("Latitude").Value).FirstOrDefault();

But this returns an empty string. 但这将返回一个空字符串。 How can I navigate the document correctly? 如何正确浏览文件?

First thing you don't need to call in multiples level Descendants method if you want to get all GeocodePoint nodes. 如果要获取所有GeocodePoint节点,则无需调用倍数级Descendants方法。 You can only do this: 您只能这样做:

XNamespace ns =  "http://schemas.microsoft.com/search/local/ws/rest/v1";
string latitude = XDocument.Load(@"test.xml")
                  .Descendants(ns+"GeocodePoint")
                  .Select(e=> (string)e.Element(ns+"Latitude"))
                  .FirstOrDefault();

With that call Linq to XML will retrieve all the GeocodePoints in your xml 通过该调用,Linq to XML将检索xml中的所有GeocodePoints

If you want to get lat and long values, then you can project either to an anonymous type or a custom class (DTO) like this: 如果要获取经度和纬度值,则可以将其投影为匿名类型或自定义类(DTO),如下所示:

XNamespace ns =  "http://schemas.microsoft.com/search/local/ws/rest/v1";

var coord= XDocument.Load(@"xml.xml")
          .Descendants(ns+"GeocodePoint").Select(e => new { Lat = (string)e.Element(ns+"Latitude"), Lng = (string)e.Element(ns+"Longitude") })
          .FirstOrDefault();

About your issue 关于你的问题

Your problem was you were calling Attribute method to get the Latitude value, but as you can see in your xml structure GeocodePoint node doesn't have that as an attribute, it is a nested element. 您的问题是您正在调用Attribute方法来获取“ Latitude值,但是正如您在xml结构中GeocodePoint节点没有将其作为属性,它是一个嵌套元素。 That's way you need to use Element method instead. 那就是您需要使用Element方法的方式。 The second issue was you need to take the namespace into account as I show above. 第二个问题是您需要考虑名称空间,如上所示。

You are not using namespace. 您没有使用名称空间。 Your Xml provided with namespace 您的Xml提供了命名空间

<Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1">

So you need to use it when searching for elements. 因此,在搜索元素时需要使用它。

XDocument doc = XDocument.Load(@"C:\tmp\data.xml");

XNamespace ns = doc.Root.Name.Namespace;
string value = doc.Root.Descendants(ns + "Latitude").FirstOrDefault().Value; 

Or search without namespace, by LocalName of element 或在没有名称空间的情况下通过元素的LocalName搜索

string value = doc.Root
                  .Descendants
                  .Where(element => element.Name.LocalName.Equals("Latitude"))
                  .FirstOrDefault()
                  .Value;

If you using Descendats method, then you can search straight for element you need. 如果使用Descendats方法,则可以直接搜索所需的元素。

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

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