Парсинг XML документа со сложной структурой - C#
Формулировка задачи:
Доброго времени суток. Возникла проблема с парсингом .osm файла. Для чтения документа решил использовать xmlReader, т.к. он лучше всего работает с большими файлами. Все было отлично пока не встретил текст такого вида:
Все атрибуты way он читает отлично, но как мне выцепить теги <nd ref="4"/> или <tag k="waterway" v="canal"/> и считать их параметры ума не приложу.
Вот пример того как файл читаю:
<way id="22845917" version="2" timestamp="2013-11-26T01:40:53Z" uid="534149" user="lurlrlrl" changeset="19120099">
<nd ref="4"/>
<nd ref="3"/>
<nd ref="2"/>
<tag k="waterway" v="canal"/>
</way>
using (XmlReader xml = XmlReader.Create("q.osm"))
{
while (xml.Read())
{
switch (xml.NodeType)
{
case XmlNodeType.Element:
// нашли элемент к примеру node
if (xml.Name == "node")
{
if (xml.HasAttributes)
{
// поиск атрибута к примеру id
while (xml.MoveToNextAttribute())
{
if (xml.Name == "id")
{
node_id = xml.Value;
}Решение задачи: «Парсинг XML документа со сложной структурой»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Xml;
namespace ConsoleApplication85
{
class Program
{
private const string NodeName = "way";
static void Main()
{
var list = new List<Way>();
using (var reader = XmlReader.Create("source.xml"))
{
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (reader.Name == NodeName)
{
var way = GetWay(reader);
list.Add(way);
}
break;
}
}
}
foreach (var way in list)
{
Console.WriteLine(way);
}
}
private static Way GetWay(XmlReader reader)
{
var attributes = AttributesToDictionary(reader);
var nds = new List<int>();
Tag tag = null;
while (reader.Read() && reader.Name != NodeName)
{
switch (reader.Name)
{
case "nd":
if (reader.MoveToNextAttribute())
nds.Add(int.Parse(reader.Value));
break;
case "tag":
var dict = AttributesToDictionary(reader);
tag = new Tag()
{
K = dict["k"],
V = dict["v"]
};
break;
}
}
return new Way
{
Id = Convert.ToInt32(attributes["id"]),
Version = Convert.ToInt32(attributes["version"]),
TimeStamp = Convert.ToDateTime(attributes["timestamp"]),
Uid = Convert.ToInt32(attributes["uid"]),
User = attributes["user"],
Changeset = Convert.ToInt64(attributes["changeset"]),
NdRefs = nds.ToArray(),
Tag = tag
};
}
private static Dictionary<string, string> AttributesToDictionary(XmlReader reader)
{
var attributes = new Dictionary<string, string>();
while (reader.MoveToNextAttribute())
{
attributes.Add(reader.Name.ToLower(), reader.Value);
}
return attributes;
}
}
public class Way
{
public int Id { get; set; }
public int Version { get; set; }
public DateTime TimeStamp { get; set; }
public int Uid { get; set; }
public string User { get; set; }
public long Changeset { get; set; }
public int[] NdRefs { get; set; }
public Tag Tag { get; set; }
}
public class Tag
{
public string K { get; set; }
public string V { get; set; }
}
}