我正在使用Visual Studio 2015并使用Visual C#/ XAML WPF项目。
我所拥有的是一个.xml文档,其中包含我想要读取,操作并将结果输出到带有特定标题的逗号分隔.csv文件的值。我相信我已经掌握了大部分代码,但嵌套元素的级别似乎存在问题。此代码成功创建了一个.csv,但它始终是空白的。
我已经尝试过.Descendants()和.Elements()部分代码,但无法将任何内容写入文件。我想我可以通过使用XDocument类来实现我的目标,并希望尽可能不使用任何其他资源。
任何帮助表示赞赏!这是我第一次在这里发帖,所以如果需要任何其他信息,我会很乐意添加更多信息。
C#代码:
private void testMethod()
{
StringBuilder sb = new StringBuilder();
string delimiter = ",";
XDocument.Load(@"C:\Users\Paulie\Desktop\Flight1.xml")
.Descendants("trk")
.Elements()
.ToList()
.ForEach(element => sb.Append(
element.Attribute("lon").Value + delimiter +
element.Attribute("lat").Value + delimiter +
element.Element("ele").Value + delimiter +
element.Element("time").Value + delimiter +
element.Element("course").Value + delimiter +
element.Element("pitch").Value + delimiter +
element.Element("roll").Value +
"\r\r"));
StreamWriter sw = new StreamWriter(@"C:\Users\Paulie\Desktop\Flight1.csv");
sw.WriteLine(sb.ToString());
sw.Close();
Console.WriteLine(sb.ToString());
}
XML源示例(不友好的版本,与XML文本中写的完全一样):
<gpx creator="Mission Planner 1.3.29 build 1.1.5646.37690" xmlns="http://www.topografix.com/GPX/1/1"><trk><trkseg><trkpt lat="30.3020034" lon="-96.4781874"><ele>89.96</ele><time>2016-08-30T08:46:16-05:00</time><course>56.32</course><roll>-3.11</roll><pitch>-5.99</pitch><mode /></trkpt><trkpt lat="30.3020015" lon="-96.4781862"><ele>89.45</ele><time>2016-08-30T08:46:19-05:00</time><course>56.3</course><roll>-3.06</roll><pitch>-6.06</pitch><mode /></trkpt><trkpt lat="30.3020013" lon="-96.4781861"><ele>89.42</ele><time>2016-08-30T08:46:19-05:00</time><course>56.3</course><roll>-3.06</roll><pitch>-6.11</pitch><mode /></trkpt><trkpt lat="30.3020012" lon="-96.478186"><ele>89.38</ele><time>2016-08-30T08:46:19-05:00</time><course>56.29</course><roll>-3.05</roll><pitch>-6.14</pitch><mode /></trkpt><trkpt lat="30.302001" lon="-96.4781859"><ele>89.35</ele><time>2016-08-30T08:46:20-05:00</time><course>56.29</course><roll>-3.06</roll><pitch>-6.13</pitch><mode /></trkpt><trkpt lat="30.3020009" lon="-96.4781858"><ele>89.32</ele><time>2016-08-30T08:46:20-05:00</time><course>56.28</course><roll>-3.07</roll><pitch>-6.17</pitch><mode /></trkpt><trkpt lat="30.3020007" lon="-96.4781856"><ele>89.29</ele><time>2016-08-30T08:46:20-05:00</time><course>56.27</course><roll>-3.08</roll><pitch>-6.17</pitch><mode /></trkpt><trkpt lat="30.3020005" lon="-96.4781855"><ele>89.25</ele><time>2016-08-30T08:46:20-05:00</time><course>56.26</course><roll>-3.1</roll><pitch>-6.2</pitch><mode /></trkpt><trkpt lat="30.3020004" lon="-96.4781854"><ele>89.22</ele><time>2016-08-30T08:46:20-05:00</time><course>56.26</course><roll>-3.1</roll><pitch>-6.21</pitch><mode /></trkpt><trkpt lat="30.3020003" lon="-96.4781853"><ele>89.2</ele><time>2016-08-30T08:46:21-05:00</time><course>56.25</course><roll>-3.1</roll><pitch>-6.24</pitch><mode /></trkpt><trkpt lat="30.3020002" lon="-96.4781852"><ele>89.17</ele><time>2016-08-30T08:46:21-05:00</time><course>56.24</course><roll>-3.12</roll><pitch>-6.26</pitch><mode /></trkpt><trkpt lat="30.302" lon="-96.4781851"><ele>89.16</ele><time>2016-08-30T08:46:21-05:00</time><course>56.23</course><roll>-3.12</roll><pitch>-6.29</pitch><mode /></trkpt><trkpt lat="30.3019999" lon="-96.478185"><ele>89.13</ele><time>2016-08-30T08:46:21-05:00</time><course>56.23</course><roll>-3.12</roll><pitch>-6.32</pitch><mode /></trkpt><trkpt lat="30.3019998" lon="-96.4781848"><ele>89.09</ele><time>2016-08-30T08:46:22-05:00</time><course>56.2</course><roll>-3.09</roll><pitch>-6.36</pitch><mode /></trkpt><trkpt lat="30.3019997" lon="-96.4781847"><ele>89.08</ele><time>2016-08-30T08:46:22-05:00</time><course>56.2</course><roll>-3.09</roll><pitch>-6.38</pitch><mode /></trkpt><trkpt lat="30.3019996" lon="-96.4781846"><ele>89.06</ele><time>2016-08-30T08:46:22-05:00</time><course>56.21</course><roll>-3.1</roll><pitch>-6.28</pitch><mode /></trkpt><trkpt lat="30.3019995" lon="-96.4781845"><ele>89.04</ele><time>2016-08-30T08:46:22-05:00</time><course>56.2</course><roll>-3.1</roll><pitch>-6.22</pitch><mode /></trkpt></trkseg></trk></gpx>
预期输出样本:
TimeStamp,SensorLatitude,SensorLongitude,SensorAltitude,PlatformHeading,PlatformPitch,PlatformRoll
1472525176000000,30.3020034,-96.4781874,89.96,56.32,-5.99,-3.11
1472525179000000,30.3020015,-96.4781862,89.45,56.3,-6.06,-3.06
1472525179000000,30.3020013,-96.4781861,89.42,56.3,-6.11,-3.06
1472525179000000,30.3020012,-96.478186,89.38,56.29,-6.14,-3.05
1472525180000000,30.302001,-96.4781859,89.35,56.29,-6.13,-3.06
1472525180000000,30.3020009,-96.4781858,89.32,56.28,-6.17,-3.07
(注意,TimeStamp列包含整数值而不是日期时间格式。这是我需要使用另一个将日期时间格式转换为Posix / Unix时间签名的函数来更改的字段)
答案 0 :(得分:0)
Elements()
获取所有子元素。当你这样做时:
.Descendants("trk").Elements()
您正在选择所有trkseg
元素(trk
元素的子元素)。您的数据位于trkpt
元素内,因此您可能需要以下内容:
XDocument.Load(@"C:\Users\Paulie\Desktop\Flight1.xml")
.Descendants("trkpt")
.ForEach(...);
此外,由于您的XML位于命名空间中,因此您需要在查找节点时指定:
.Descendants("{http://www.topografix.com/GPX/1/1}trkpt")
答案 1 :(得分:0)
另一种方法:
string[] valuesToPrint = { "lon", "lat", "ele", "time", "course", "pitch", "roll" };
XNamespace ns = "http://www.topografix.com/GPX/1/1";
File.WriteAllLines("Flight1.csv",
new[] { string.Join(",", valuesToPrint) }
.Concat(XDocument.Load("Flight1.xml")
.Descendants(ns + "trkpt")
.Select(e =>
{
return string.Join(",", e.Attributes()
.Where(a => valuesToPrint.Contains(a.Name.LocalName))
.Select(a => a.Value)
.Concat(e.Elements()
.Where(c => valuesToPrint.Contains(c.Name.LocalName))
.Select(c => c.Value)).ToArray());
})));
使用测试XML输出:
lon,lat,ele,time,course,pitch,roll
-96.4781874,30.3020034,89.96,2016-08-30T08:46:16-05:00,56.32,-3.11,-5.99
-96.4781862,30.3020015,89.45,2016-08-30T08:46:19-05:00,56.3,-3.06,-6.06
-96.478186,30.3020012,89.38,2016-08-30T08:46:19-05:00,56.29,-3.05,-6.14
-96.4781859,30.302001,89.35,2016-08-30T08:46:20-05:00,56.29,-3.06,-6.13
-96.4781858,30.3020009,89.32,2016-08-30T08:46:20-05:00,56.28,-3.07,-6.17
由于我不确定您希望输出的确切格式,这可能有点不合适!
这分解如下:
valuesToPrint
中的所有属性和子元素的值,并用逗号连接这些值。答案 2 :(得分:0)
在使用原始XML源一段时间之后,我意识到在文件的开头和结尾有一堆额外的数据是完全没必要的,只会导致我的程序出现问题。
我最终做的是切断XML代码的开头和结尾部分(使用和作为开始和结束索引),以便我可以轻松地使用我将XML结构转换为CSV结构的原始方法。
现在一切正常!感谢所有花时间帮助我的人。