1 | using System.Xml;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using System;
|
---|
4 | using System.Collections;
|
---|
5 | using System.IO;
|
---|
6 |
|
---|
7 | namespace Persistence {
|
---|
8 | public class XmlParser : IEnumerable<IParseToken> {
|
---|
9 |
|
---|
10 | private XmlReader reader;
|
---|
11 | private delegate IEnumerator<IParseToken> Handler();
|
---|
12 | private Dictionary<string, Handler> handlers;
|
---|
13 |
|
---|
14 | public XmlParser(StreamReader input) {
|
---|
15 | XmlReaderSettings settings = new XmlReaderSettings();
|
---|
16 | settings.ConformanceLevel = ConformanceLevel.Document;
|
---|
17 | settings.IgnoreWhitespace = true;
|
---|
18 | settings.IgnoreComments = true;
|
---|
19 | this.reader = XmlReader.Create(input, settings);
|
---|
20 | this.handlers = new Dictionary<string, Handler>();
|
---|
21 | this.handlers.Add("PRIMITIVE", new Handler(ParsePrimitive));
|
---|
22 | this.handlers.Add("COMPOSITE", new Handler(ParseComposite));
|
---|
23 | this.handlers.Add("REFERENCE", new Handler(ParseReference));
|
---|
24 | this.handlers.Add("NULL", new Handler(ParseNull));
|
---|
25 | }
|
---|
26 | public IEnumerator<IParseToken> GetEnumerator() {
|
---|
27 | while (this.reader.Read()) {
|
---|
28 | if (!reader.IsStartElement()) {
|
---|
29 | break;
|
---|
30 | }
|
---|
31 | IEnumerator<IParseToken> iterator;
|
---|
32 | try {
|
---|
33 | iterator = handlers[reader.Name].Invoke();
|
---|
34 | }
|
---|
35 | catch (KeyNotFoundException) {
|
---|
36 | throw new InvalidOperationException(String.Format(
|
---|
37 | "No handler for XML tag \"{0}\" installed",
|
---|
38 | reader.Name));
|
---|
39 | }
|
---|
40 | while (iterator.MoveNext()) {
|
---|
41 | yield return iterator.Current;
|
---|
42 | }
|
---|
43 | }
|
---|
44 | }
|
---|
45 | private IEnumerator<IParseToken> ParsePrimitive() {
|
---|
46 | yield return new Primitive(
|
---|
47 | this.reader.GetAttribute("name"),
|
---|
48 | Type.GetType(this.reader.GetAttribute("type")),
|
---|
49 | this.reader.ReadString());
|
---|
50 | }
|
---|
51 | private IEnumerator<IParseToken> ParseComposite() {
|
---|
52 | string name = this.reader.GetAttribute("name");
|
---|
53 | Type type = Type.GetType(this.reader.GetAttribute("type"));
|
---|
54 | int id = int.Parse(this.reader.GetAttribute("id"));
|
---|
55 | yield return new CompositeStart(name, type, id);
|
---|
56 | IEnumerator<IParseToken> iterator = this.GetEnumerator();
|
---|
57 | while (iterator.MoveNext())
|
---|
58 | yield return iterator.Current;
|
---|
59 | yield return new CompositeEnd(name, type, id);
|
---|
60 | }
|
---|
61 | private IEnumerator<IParseToken> ParseReference() {
|
---|
62 | yield return new Reference(
|
---|
63 | this.reader.GetAttribute("name"),
|
---|
64 | int.Parse(this.reader.GetAttribute("ref")));
|
---|
65 | }
|
---|
66 | private IEnumerator<IParseToken> ParseNull() {
|
---|
67 | yield return new Null(this.reader.GetAttribute("name"));
|
---|
68 | }
|
---|
69 | IEnumerator IEnumerable.GetEnumerator() {
|
---|
70 | return this.GetEnumerator();
|
---|
71 | }
|
---|
72 | }
|
---|
73 | }
|
---|