增强XML解析的复杂性-C#XML循环 [英] Enhance XML Parsing complexity - c# XML Looping

查看:103
本文介绍了增强XML解析的复杂性-C#XML循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写自己的c#自定义地图导航程序.我正在使用 OpenStreetMaps 作为地图数据.这是一个大型XML文件,其中包含节点和方式.我写了一个转换器,将XML文件从无用的垃圾中删除(例如时间戳,用户等),以使文件变小.

I am writing my own c# custom map navigation program. I am using OpenStreetMaps for the map data. It's a large XML file that contains Nodes and ways. I wrote a convertor that strips the XML file from useless junk (like timestamp, user etc) so the file will become smaller.

现在,当我尝试遍历XML并将数据转换为C#对象的方式和节点时,遇到了一个问题.我需要做很多循环,以至于加载时间太长.

Now while I attempt to loop through the XML and convert the data to C# object Ways and Nodes I came across a problem. I need to do so much looping that the loading time is way too long.

XML示例(w =方式,n =节点,rf =引用节点):

      <n id="2638006578" l="5.9295547" b="52.5619519" />
      <n id="2638006579" l="5.9301973" b="52.5619526" />
      <n id="2638006581" l="5.9303625" b="52.5619565" />
      <n id="2638006583" l="5.9389539" b="52.5619577" />
      <n id="2638006589" l="5.9386643" b="52.5619733" />
      <n id="2638006590" l="5.9296231" b="52.5619760" />
      <n id="2638006595" l="5.9358987" b="52.5619864" />
      <n id="2638006596" l="5.9335913" b="52.5619865" />
      <w id="453071384">
        <nd rf="2638006581" />
        <nd rf="2638006590" />
        <nd rf="2638006596" />
        <nd rf="2638006583" />
        <nd rf="2638006578" />
      </w>
      <w id="453071385">
        <nd rf="2638006596" />
        <nd rf="2638006578" />
        <nd rf="2638006581" />
        <nd rf="2638006583" />
      </w>

  • 方式"节点包含对节点的引用,因此一个节点可以多种方式存在(节点连接方式).

    • The Way nodes contain references to nodes, so a node can be existent in multiple ways (the nodes connect the ways).

      节点包含经度和纬度(l = lon,b = lat).

      nodes contain a longitude and latitude (l = lon, b = lat).

      这些XML文件包含很多节点和方式,因此它不仅仅是一个小文件.下面的代码示例中的XML文件有50万行.

      These XML files contain a lot of nodes and ways, so it's not just a small file. The XML file in the code example below has 500K lines.

      我的代码

      class Program {
      
              static List<Way> ways = new List<Way>();
              static List<Node> nodes = new List<Node>();
      
              static void Main(String[] args) {
                  read();
              }
              public static void read() {
                  String xmlLoc = @"C:\Users\MyName\Desktop\result.xml";
                  long time = DateTime.Now.Ticks;
                  Parse(xmlLoc);
                  long time2 = DateTime.Now.Ticks;
                  Console.WriteLine("Done: {0} ms", (time2 - time) / 10000);
                  Console.WriteLine(" - Nodes Amount:" + nodes.Count());
                  Console.WriteLine(" - Ways Amount: " + ways.Count());
              }
      
              private static Node GetByRef(long reference) {
                  return nodes.First(x => x.ID == reference);
              }
      
              private static void Parse(string path) {
                  using (XmlReader reader = XmlReader.Create(path)) {
                      reader.MoveToContent();
                      while (reader.Read()) {
                          if (reader.NodeType == XmlNodeType.Element) {
                              XElement element = XElement.ReadFrom(reader) as XElement;
                              if ( element.Name.ToString().Equals("w")) {
                                  Way w = new Way();
                                  var name = element.Attribute("nm");
                                  if (name != null) w.Name = name.Value;
                                  var children = element.Descendants("nd");
                                  foreach (XElement child in children) w.References.Add(long.Parse(child.Attribute("rf").Value));
                                  ways.Add(w);
                              }else if (element.Name.ToString().Equals("n")) {
                                  Node n = new Node();
                                  n.ID = long.Parse(element.Attribute("id").Value);
                                  n.Lon = double.Parse(element.Attribute("l").Value);
                                  n.Lat = double.Parse(element.Attribute("b").Value);
                                  nodes.Add(n);
                              }
                          }
                      }
                  }
              }
          }
      
          class Way {
      
              public List<long> References { get; private set; }
              public long ID { get; set; }
              public String Name { get; set; }
              public bool OneWay { get; set; }
      
              public Way() {
                  this.References = new List<long>();
              }
          }
      
          class Node {
              public long ID { get; set; }
              public double Lat { get; set; }
              public double Lon { get; set; }
          }
      

      当前,类Way和Node之间没有实际关系.只有一个具有long值的列表.我不知何故需要在Way类中添加一个带有Nodes的列表,但这将需要我处理另一个(两个?)for/while循环.我相信那将意味着O(N4),这很慢.

      Currently there's no actual relation between the class Way and the class Node. There's only a list with long values. I somehow need to add a list with Nodes to the class Way, but that'll require me to work with another (two?) for/while loops. That would mean O(N4) I believe, which is slow.

      从技术上讲,我正在寻找一种解决方案和更好地构建此解决方案的方法,如果您有建议,我想听听它!

      Technically I am looking for both a solution and ways to build this better, if you have advise I'd like to hear it!

      提前谢谢!

      PS::如果我应该更新/编辑问题,请告诉我,而不是立即投票.

      PS: If I should update/edit my question, please tell me instead of downvoting immediately.

      推荐答案

      使用xml linq

      Use xml linq

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Data;
      using System.Xml;
      using System.Xml.Linq;
      using System.IO;
      
      
      namespace ConsoleApplication31
      {
          class Program
          {
              const string FILENAME = @"c:\temp\test.xml";
              static void Main(string[] args)
              {
      
                  XDocument xdoc = XDocument.Load(FILENAME);
      
                  var results = xdoc.Elements("root").Select(x => new
                  {
                      ns = x.Descendants("n").Select(y => new {
                          id = (long)y.Attribute("id"),
                          l = (double)y.Attribute("l"),
                          b = (double)y.Attribute("b")
                      }).ToList(),
                      ws = x.Descendants("w").Select(y => new {
                          id = (long)y.Attribute("id"),
                          rfs= y.Descendants("nd").Select(z => (long)z.Attribute("rf")).ToList()
                      }).ToList()
                  }).FirstOrDefault();
      
              }
          }
      
      }
      

      这篇关于增强XML解析的复杂性-C#XML循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆