Use XDocument instead of XmlDocument

This commit is contained in:
ClemensF 2019-11-07 22:34:25 +01:00
parent 2c8bca205e
commit d2638c4a6c
5 changed files with 45 additions and 99 deletions

View file

@ -6,12 +6,12 @@ using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using System.Threading.Tasks;
#if WINDOWS_UWP
using Windows.Data.Xml.Dom;
using Windows.UI.Xaml;
#else
using System.Windows;
using System.Xml;
#endif
namespace MapControl
@ -23,6 +23,8 @@ namespace MapControl
/// </summary>
public class BingMapsTileLayer : MapTileLayer
{
private static readonly XNamespace imageryMetadataNamespace = "http://schemas.microsoft.com/search/local/ws/rest/v1";
public enum MapMode
{
Road, Aerial, AerialWithLabels
@ -47,7 +49,7 @@ namespace MapControl
public string Culture { get; set; }
public Uri LogoImageUri { get; private set; }
private async void OnLoaded(object sender, RoutedEventArgs e)
private async void OnLoaded(object sender, RoutedEventArgs args)
{
Loaded -= OnLoaded;
@ -57,74 +59,59 @@ namespace MapControl
return;
}
var imageryMetadataUrl = "http://dev.virtualearth.net/REST/V1/Imagery/Metadata/" + Mode;
var uri = "http://dev.virtualearth.net/REST/V1/Imagery/Metadata/" + Mode + "?output=xml&key=" + ApiKey;
try
{
var uri = new Uri(imageryMetadataUrl + "?output=xml&key=" + ApiKey);
var document = await XmlDocument.LoadFromUriAsync(uri);
var imageryMetadata = document.DocumentElement.GetElementsByTagName("ImageryMetadata").OfType<XmlElement>().FirstOrDefault();
var document = await Task.Run(() => XDocument.Load(uri));
var imageryMetadata = document.Descendants(imageryMetadataNamespace + "ImageryMetadata").FirstOrDefault();
var brandLogoUri = document.Descendants(imageryMetadataNamespace + "BrandLogoUri").FirstOrDefault();
if (imageryMetadata != null)
{
ReadImageryMetadata(imageryMetadata);
}
var brandLogoUri = document.DocumentElement.GetElementsByTagName("BrandLogoUri").OfType<XmlElement>().FirstOrDefault();
if (brandLogoUri != null)
{
LogoImageUri = new Uri(brandLogoUri.InnerText);
LogoImageUri = new Uri(brandLogoUri.Value);
}
}
catch (Exception ex)
{
Debug.WriteLine("BingMapsTileLayer: {0}: {1}", imageryMetadataUrl, ex.Message);
Debug.WriteLine("BingMapsTileLayer: {0}: {1}", uri, ex.Message);
}
}
private void ReadImageryMetadata(XmlElement imageryMetadata)
private void ReadImageryMetadata(XElement imageryMetadata)
{
string imageUrl = null;
string[] imageUrlSubdomains = null;
int? zoomMin = null;
int? zoomMax = null;
var imageUrl = imageryMetadata.Element(imageryMetadataNamespace + "ImageUrl")?.Value;
var imageUrlSubdomains = imageryMetadata.Element(imageryMetadataNamespace + "ImageUrlSubdomains")?
.Elements()
.Where(e => e.Name.LocalName == "string")
.Select(e => e.Value)
.ToArray();
foreach (var element in imageryMetadata.ChildNodes.OfType<XmlElement>())
if (!string.IsNullOrEmpty(imageUrl) &&
imageUrlSubdomains != null &&
imageUrlSubdomains.Length > 0)
{
switch ((string)element.LocalName)
{
case "ImageUrl":
imageUrl = element.InnerText;
break;
case "ImageUrlSubdomains":
imageUrlSubdomains = element.ChildNodes
.OfType<XmlElement>()
.Where(e => (string)e.LocalName == "string")
.Select(e => e.InnerText)
.ToArray();
break;
case "ZoomMin":
zoomMin = int.Parse(element.InnerText);
break;
case "ZoomMax":
zoomMax = int.Parse(element.InnerText);
break;
default:
break;
}
}
var zoomMin = imageryMetadata.Element(imageryMetadataNamespace + "ZoomMin")?.Value;
var zoomMax = imageryMetadata.Element(imageryMetadataNamespace + "ZoomMax")?.Value;
int z;
if (!string.IsNullOrEmpty(imageUrl) && imageUrlSubdomains != null && imageUrlSubdomains.Length > 0)
{
if (zoomMin.HasValue && zoomMin.Value > MinZoomLevel)
if (!string.IsNullOrEmpty(zoomMin) &&
int.TryParse(zoomMin, out z) &&
MinZoomLevel < z)
{
MinZoomLevel = zoomMin.Value;
MinZoomLevel = z;
}
if (zoomMax.HasValue && zoomMax.Value < MaxZoomLevel)
if (!string.IsNullOrEmpty(zoomMax) &&
int.TryParse(zoomMax, out z) &&
MaxZoomLevel > z)
{
MaxZoomLevel = zoomMax.Value;
MaxZoomLevel = z;
}
if (string.IsNullOrEmpty(Culture))

View file

@ -8,13 +8,12 @@ using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Globalization;
using System.Xml.Linq;
#if WINDOWS_UWP
using Windows.Data.Xml.Dom;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
#else
using System.Xml;
using System.Windows;
using System.Windows.Media;
#endif
@ -23,6 +22,8 @@ namespace MapControl
{
public partial class WmsImageLayer : MapImageLayer
{
private static readonly XNamespace wmsNamespace = "http://www.opengis.net/wms";
public static readonly DependencyProperty ServiceUriProperty = DependencyProperty.Register(
nameof(ServiceUri), typeof(Uri), typeof(WmsImageLayer),
new PropertyMetadata(null, async (o, e) => await ((WmsImageLayer)o).UpdateImageAsync()));
@ -72,29 +73,17 @@ namespace MapControl
if (ServiceUri != null)
{
var uri = GetRequestUri("GetCapabilities");
var uri = GetRequestUri("GetCapabilities").Replace(" ", "%20");
try
{
var document = await XmlDocument.LoadFromUriAsync(new Uri(uri.Replace(" ", "%20")));
layerNames = new List<string>();
var capability = ChildElements(document.DocumentElement, "Capability").FirstOrDefault();
if (capability != null)
{
var rootLayer = ChildElements(capability, "Layer").FirstOrDefault();
if (rootLayer != null)
{
foreach (var layer in ChildElements(rootLayer, "Layer"))
{
var name = ChildElements(layer, "Name").FirstOrDefault();
if (name != null)
{
layerNames.Add(name.InnerText);
}
}
}
}
layerNames = await Task.Run(() =>
XDocument.Load(uri)
.Descendants(wmsNamespace + "Layer")
.Where(e => e.Attribute("queryable")?.Value == "1")
.Select(e => e.Element(wmsNamespace + "Name")?.Value)
.Where(n => !string.IsNullOrEmpty(n))
.ToList());
}
catch (Exception ex)
{
@ -200,10 +189,5 @@ namespace MapControl
return uri + "REQUEST=" + request;
}
private static IEnumerable<XmlElement> ChildElements(XmlElement element, string name)
{
return element.ChildNodes.OfType<XmlElement>().Where(e => (string)e.LocalName == name);
}
}
}

View file

@ -80,7 +80,6 @@
<Compile Include="..\WPF\Tile.WPF.cs" Link="Tile.WPF.cs" />
<Compile Include="..\WPF\TileImageLoader.WPF.cs" Link="TileImageLoader.WPF.cs" />
<Compile Include="..\WPF\TypeConverters.WPF.cs" Link="TypeConverters.WPF.cs" />
<Compile Include="..\WPF\XmlDocument.WPF.cs" Link="XmlDocument.WPF.cs" />
</ItemGroup>
<ItemGroup>

View file

@ -47,10 +47,11 @@
<Reference Include="System" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Xml" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
@ -195,7 +196,6 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Tile.WPF.cs" />
<Compile Include="XmlDocument.WPF.cs" />
<None Include="..\..\MapControl.snk">
<Link>MapControl.snk</Link>
</None>

View file

@ -1,24 +0,0 @@
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
// © 2019 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using System.Threading.Tasks;
namespace MapControl
{
internal class XmlDocument : System.Xml.XmlDocument
{
public static XmlDocument LoadFromUri(Uri uri)
{
var document = new XmlDocument();
document.Load(uri.ToString());
return document;
}
public static Task<XmlDocument> LoadFromUriAsync(Uri uri)
{
return Task.Run(() => LoadFromUri(uri));
}
}
}