使用 XDocument.Load 加载 XML 的后代
Loading Descendants of XML using XDocument.Load
我正在尝试使用 XDocument.Load 访问一些纬度和经度数字。这是示例 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>
这是我试图访问纬度和经度的代码;
string latitude = XDocument.Load(@"test.xml").Root
.Descendants("ResourceSets")
.Descendants("ResourceSet")
.Descendants("Resources")
.Descendants("Location")
.Descendants("GeocodePoint")
.Select(element => element.Attribute("Latitude").Value).FirstOrDefault();
但是这个 returns 是一个空字符串。如何正确浏览文档?
首先,如果您想获取所有 GeocodePoint
节点,则无需调用多级 Descendants
方法。你只能这样做:
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();
通过对 XML 的调用 Linq 将检索 xml
中的所有 GeocodePoints
如果你想获得纬度和经度值,那么你可以投影到匿名类型或自定义类型 class (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();
关于您的问题
您的问题是您正在调用 Attribute
方法来获取 Latitude
值,但是正如您在 xml 结构中看到的 GeocodePoint
节点没有作为一个属性,它是一个嵌套元素。这就是您需要使用 Element
方法的方式。第二个问题是您需要考虑我上面显示的命名空间。
您没有使用命名空间。您的 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">
所以搜索元素的时候需要用到。
XDocument doc = XDocument.Load(@"C:\tmp\data.xml");
XNamespace ns = doc.Root.Name.Namespace;
string value = doc.Root.Descendants(ns + "Latitude").FirstOrDefault().Value;
或者不带命名空间的搜索,通过 LocalName
of element
string value = doc.Root
.Descendants
.Where(element => element.Name.LocalName.Equals("Latitude"))
.FirstOrDefault()
.Value;
如果您使用Descendats
方法,那么您可以直接搜索您需要的元素。
我正在尝试使用 XDocument.Load 访问一些纬度和经度数字。这是示例 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>
这是我试图访问纬度和经度的代码;
string latitude = XDocument.Load(@"test.xml").Root
.Descendants("ResourceSets")
.Descendants("ResourceSet")
.Descendants("Resources")
.Descendants("Location")
.Descendants("GeocodePoint")
.Select(element => element.Attribute("Latitude").Value).FirstOrDefault();
但是这个 returns 是一个空字符串。如何正确浏览文档?
首先,如果您想获取所有 GeocodePoint
节点,则无需调用多级 Descendants
方法。你只能这样做:
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();
通过对 XML 的调用 Linq 将检索 xml
中的所有GeocodePoints
如果你想获得纬度和经度值,那么你可以投影到匿名类型或自定义类型 class (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();
关于您的问题
您的问题是您正在调用 Attribute
方法来获取 Latitude
值,但是正如您在 xml 结构中看到的 GeocodePoint
节点没有作为一个属性,它是一个嵌套元素。这就是您需要使用 Element
方法的方式。第二个问题是您需要考虑我上面显示的命名空间。
您没有使用命名空间。您的 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">
所以搜索元素的时候需要用到。
XDocument doc = XDocument.Load(@"C:\tmp\data.xml");
XNamespace ns = doc.Root.Name.Namespace;
string value = doc.Root.Descendants(ns + "Latitude").FirstOrDefault().Value;
或者不带命名空间的搜索,通过 LocalName
of element
string value = doc.Root
.Descendants
.Where(element => element.Name.LocalName.Equals("Latitude"))
.FirstOrDefault()
.Value;
如果您使用Descendats
方法,那么您可以直接搜索您需要的元素。