1 using System;
2 using System.Collections;
3
4
5
6
7
8 namespace System.Dom
9 {
10 public enum Flags : int
11 {
12 none = 0, debug = 1 << 0
13 }
14 public inline Flags operator&(Flags flags, Flags flag)
15 {
16 return cast<Flags>(cast<int>(flags) & cast<int>(flag));
17 }
18 public inline Flags operator|(Flags flags, Flags flag)
19 {
20 return cast<Flags>(cast<int>(flags) | cast<int>(flag));
21 }
22 public inline Flags operator~(Flags flags)
23 {
24 return cast<Flags>(~cast<int>(flags));
25 }
26 public class DomDocumentHandler : System.Xml.XmlContentHandler
27 {
28 public DomDocumentHandler() :
29 document(new Document())
30 {
31 }
32 public UniquePtr<Document> GetDocument()
33 {
34 return Rvalue(document);
35 }
36 public void AddTextContent()
37 {
38 AddTextContent(false);
39 }
40 public void AddTextContent(bool addSpace)
41 {
42 if (!currentElement.IsNull())
43 {
44 ustring text = TrimAll(textContent);
45 if (!text.IsEmpty())
46 {
47 if (addSpace)
48 {
49 text.Append(' ', 1);
50 }
51 UniquePtr<Node> textNode(new System.Dom.Text(text));
52 currentElement->AppendChild(Rvalue(textNode));
53 }
54 }
55 textContent.Clear();
56 }
57 public override void StartDocument()
58 {
59 }
60 public override void EndDocument()
61 {
62 }
63 public override void Version(const ustring& xmlVersion)
64 {
65 document->SetXmlVersion(xmlVersion);
66 }
67 public override void Standalone(bool standalone)
68 {
69 document->SetXmlStandalone(standalone);
70 }
71 public override void Encoding(const ustring& encoding)
72 {
73 document->SetXmlEncoding(encoding);
74 }
75 public override void HandleText(const ustring& text)
76 {
77 textContent.Append(text);
78 }
79 public override void HandleComment(const ustring& comment)
80 {
81 AddTextContent();
82 UniquePtr<Node> commentNode(new Comment(comment));
83 if (!currentElement.IsNull())
84 {
85 currentElement->AppendChild(Rvalue(commentNode));
86 }
87 else
88 {
89 document->AppendChild(Rvalue(commentNode));
90 }
91 }
92 public override void HandlePI(const ustring& target, const ustring& data)
93 {
94 AddTextContent();
95 UniquePtr<Node> processingInstructionNode(new ProcessingInstruction(target, data));
96 if (!currentElement.IsNull())
97 {
98 currentElement->AppendChild(Rvalue(processingInstructionNode));
99 }
100 else
101 {
102 document->AppendChild(Rvalue(processingInstructionNode));
103 }
104 }
105 public override void HandleCDataSection(const ustring& data)
106 {
107 AddTextContent();
108 UniquePtr<Node> cdataSection(new CDataSection(data));
109 if (!currentElement.IsNull())
110 {
111 currentElement->AppendChild(Rvalue(cdataSection));
112 }
113 else
114 {
115 document->AppendChild(Rvalue(cdataSection));
116 }
117 }
118 public override void StartElement(const ustring& namespaceUri, const ustring& localName, const ustring& qualifiedName, const System.Xml.Attributes& attributes)
119 {
120 AddTextContent(true);
121 elementStack.Push(Rvalue(currentElement));
122 Map<ustring, Attr*> attrs;
123 for (const System.Xml.Attribute& attr : attributes)
124 {
125 attrs[attr.QualifiedName()] = new Attr(attr.QualifiedName(), attr.Value());
126 }
127 currentElement.Reset(new Element(qualifiedName, Rvalue(attrs)));
128 currentElement->InternalSetOwnerDocument(document.Get());
129 if (!namespaceUri.IsEmpty())
130 {
131 currentElement->InternalSetNamespaceUri(namespaceUri);
132 }
133 }
134 public override void EndElement(const ustring& namespaceUri, const ustring& localName, const ustring& qualifiedName)
135 {
136 AddTextContent();
137 UniquePtr<Element> parentElement = Rvalue(elementStack.Top());
138 elementStack.Pop();
139 if (!parentElement.IsNull())
140 {
141 parentElement->AppendChild(UniquePtr<Node>(currentElement.Release()));
142 currentElement = Rvalue(parentElement);
143 }
144 else
145 {
146 document->AppendChild(UniquePtr<Node>(currentElement.Release()));
147 }
148 }
149 public override void SkippedEntity(const ustring& entityName)
150 {
151 }
152 private UniquePtr<Document> document;
153 private UniquePtr<Element> currentElement;
154 private Stack<UniquePtr<Element>> elementStack;
155 private ustring textContent;
156 }
157 public UniquePtr<Document> ParseDocument(const ustring& content, const string& systemId)
158 {
159 return ParseDocument(content, systemId, Flags.none);
160 }
161 public UniquePtr<Document> ParseDocument(const ustring& content, const string& systemId, Flags flags)
162 {
163 DomDocumentHandler domDocumentHandler;
164 System.Xml.Flags xmlFlags = System.Xml.Flags.none;
165 if ((flags & Flags.debug) != Flags.none)
166 {
167 xmlFlags = xmlFlags | System.Xml.Flags.debug;
168 }
169 System.Xml.ParseXmlContent(content, systemId, &domDocumentHandler, xmlFlags);
170 return domDocumentHandler.GetDocument();
171 }
172 public UniquePtr<Document> ReadDocument(const string& fileName)
173 {
174 return ReadDocument(fileName, Flags.none);
175 }
176 public UniquePtr<Document> ReadDocument(const string& fileName, Flags flags)
177 {
178 ustring content = ToUtf32(System.IO.File.ReadAllText(fileName));
179 return ParseDocument(content, fileName, flags);
180 }
181 }