source: branches/New Persistence Exploration/Persistence/Persistence/XmlParser.cs @ 1339

Last change on this file since 1339 was 1339, checked in by epitzer, 12 years ago

support composite value types (#506)

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