-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathXmlParser.cs
143 lines (127 loc) · 5.83 KB
/
XmlParser.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
namespace MicroFramework.Xml
{
using System;
public class XmlParser
{
private string inputString;
private int currPos = 0;
public XmlParser(string input)
{
this.inputString = input;
this.currPos = 0;
}
public void ReadElement(ref XElem root)
{
int posSpace = 0;
int posNameEnd = 0;
XElem node;
while (currPos < this.inputString.Length)
{
switch (this.inputString[currPos])
{
case '<': // Start of Element or end of long Element
if (this.inputString[currPos + 1] == '/')
{
// Check for end of long Element
if (this.inputString.Substring(currPos, root.Name.Length + 3) == "</" + root.Name + ">")
{
// long tag form element close
currPos = currPos + (root.Name.Length + 3);
return;
}
throw new InvalidOperationException("Unmatched elements at " + currPos + ". Expected '" + root.Name + "', found '" + this.inputString.Substring(currPos, 10));
}
else
{
// Start of Element
if (this.inputString[currPos + 1] == '?')
{
// Skip Xml declaration
posNameEnd = this.inputString.IndexOf(">", currPos);
currPos = currPos + posNameEnd;
}
else
{
node = new XElem();
posNameEnd = this.inputString.IndexOf(">", currPos);
posSpace = this.inputString.IndexOf(" ", currPos);
// If there is a space between opening and the closing bracket...
if ((posSpace > 0) && (posSpace < posNameEnd))
{
// ... then attributes are present, so read them
int off = 0;
node.Name = this.inputString.Substring(currPos + 1, posSpace - currPos - 1);
currPos = posSpace + 1;
if (this.inputString[posNameEnd - 1] == '/')
{
// Account for short form
off = 1;
}
node.Attributes = ReadAttributes(this.inputString.Substring(currPos, posNameEnd - currPos - off));
currPos = posNameEnd + 1;
}
else
{
// .. otherwise no attributes are present
node.Name = this.inputString.Substring(currPos + 1, posNameEnd - currPos - 1);
currPos = posNameEnd + 1;
node.Attributes = null;
}
// Did we just read the root node?
if (root == null)
{
// Yes, so set.
root = node;
}
else
{
// No, so add as child to passed in node.
root.AddChild(node);
}
// If we are not a shortform, recurse down to read the next element.
if (this.inputString[posNameEnd - 1] != '/')
{
// Not a shortform tag
ReadElement(ref node);
}
}
}
break;
case '/':
// Single tag element closing
if (this.inputString[currPos + 1] == '>')
{
currPos = currPos + 2;
return;
}
else
{
currPos = currPos + 1;
}
break;
default:
currPos = currPos + 1;
break;
}
}
}
private XAttributeList ReadAttributes(string attrString)
{
string[] attrParts = null;
XAttributeList objAttributes = new XAttributeList();
foreach (string attrPair in attrString.Trim().Split(' '))
{
if (attrPair != string.Empty)
{
attrParts = attrPair.Split('=');
if (attrParts.Length == 2)
{
// remove quotes from value
objAttributes.Add(new XAttribute(attrParts[0], attrParts[1].Trim("\"".ToCharArray())));
}
}
}
return objAttributes;
}
}
}