【问题标题】:How do I select items in an XDocument?如何选择 XDocument 中的项目?
【发布时间】:2016-04-27 05:40:19
【问题描述】:

在下面的 XML 中,我试图检索所有 trkpt 项目,以便我可以使用 lat / lon 属性值执行任务。我认为 LINQ to XML 将是最简单的方法,但我无法在 foreach 循环中返回任何结果。我做错了什么?

此代码位于控制台应用程序的 Main() 方法中:

var filename = @"C:\temp\sample_output.gpx";

var xDoc = XDocument.Load(filename);

XNamespace xmlns = "http://www.topografix.com/GPX/1/1";
XNamespace gpxtpx = "http://www.garmin.com/xmlschemas/TrackPointExtension/v1";
XNamespace wptx1 = "http://www.garmin.com/xmlschemas/WaypointExtension/v1";
XNamespace gpxx = "http://www.garmin.com/xmlschemas/GpxExtensions/v3";
XNamespace gpxtrkx = "http://www.garmin.com/xmlschemas/TrackStatsExtension/v1";

foreach (var item in xDoc.Descendants(gpxtpx + "trkpt"))
{
    Console.WriteLine(item.Element(gpxtpx + "trkpt").Value);
}

Console.Read();

我正在尝试使用上述代码处理的 XML 数据。修改了纬度/经度值。

 <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
    <gpx xmlns="http://www.topografix.com/GPX/1/1"
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"
xmlns:gpxtrkx="http://www.garmin.com/xmlschemas/TrackStatsExtension/v1"
xmlns:wptx1="http://www.garmin.com/xmlschemas/WaypointExtension/v1"
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
creator="Oregon 600" version="1.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1
http://www.topografix.com/GPX/1/1/gpx.xsd
http://www.garmin.com/xmlschemas/GpxExtensions/v3
http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd
http://www.garmin.com/xmlschemas/TrackStatsExtension/v1
http://www8.garmin.com/xmlschemas/TrackStatsExtension.xsd
http://www.garmin.com/xmlschemas/WaypointExtension/v1
http://www8.garmin.com/xmlschemas/WaypointExtensionv1.xsd
http://www.garmin.com/xmlschemas/TrackPointExtension/v1
http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd">
        <metadata>
            <link href="http://www.garmin.com">
                <text>Garmin International</text>
            </link>
            <time>2016-04-18T01:19:07Z</time>
        </metadata>
        <trk>
            <name>2016-04-17 20:19:01</name>
            <extensions>
                <gpxx:TrackExtension>
                    <gpxx:DisplayColor>Magenta</gpxx:DisplayColor>
                </gpxx:TrackExtension>
            </extensions>
            <trkseg>
                <trkpt lat="44.123" lon="-89.123">
                    <ele>343.61</ele>
                    <time>2016-04-17T22:53:34Z</time>
                </trkpt>
                <trkpt lat="44.123" lon="-89.123">
                    <ele>343.58</ele>
                    <time>2016-04-17T22:53:35Z</time>
                </trkpt>
                <trkpt lat="44.123" lon="-89.123">
                    <ele>343.56</ele>
                    <time>2016-04-17T22:53:36Z</time>
                </trkpt>
                <trkpt lat="44.123" lon="-89.123">
                    <ele>343.55</ele>
                    <time>2016-04-17T22:53:37Z</time>
                </trkpt>
                <trkpt lat="44.123" lon="-89.123">
                    <ele>343.62</ele>
                    <time>2016-04-17T22:53:38Z</time>
                </trkpt>
            </trkseg>
        </trk>
    </gpx>

【问题讨论】:

    标签: c# xml linq-to-xml


    【解决方案1】:

    您使用了错误的命名空间。元素的默认命名空间(包括trkpt)是http://www.topografix.com/GPX/1/1,原因如下:

    xmlns="http://www.topografix.com/GPX/1/1"
    

    我强烈建议您将变量名称更改为gpxNs 以指示其值,然后使用它:

    XNamespace gpxNs = "http://www.topografix.com/GPX/1/1";
    ...
    foreach (var item in xDoc.Descendants(gpxNs + "trkpt"))
    

    【讨论】:

    • 一个类似但更复杂的问题,你能看一下吗? link
    【解决方案2】:

    你可以用 XML Linq 做到这一点

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XDocument doc = XDocument.Load(FILENAME);
    
                XElement trkseg = doc.Descendants().Where(x => x.Name.LocalName == "trkseg").FirstOrDefault();
                XNamespace ns = trkseg.Name.Namespace;
    
                var l_l = trkseg.Elements(ns + "trkpt").Select(x => new
                {
                    lat = x.Attribute("lat").Value,
                    lon = x.Attribute("lon").Value
                }).ToList();
    
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 2018-01-03
      • 2015-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多