This repository has been archived by the owner on Feb 20, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 820
/
XMLViewer.cs
211 lines (188 loc) · 7.89 KB
/
XMLViewer.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/****************************** Module Header ******************************\
* Module Name: XMLViewer.cs
* Project: CSRichTextBoxSyntaxHighlighting
* Copyright (c) Microsoft Corporation.
*
* This XMLViewer class inherits System.Windows.Forms.RichTextBox and it is used
* to display an Xml in a specified format.
*
* RichTextBox uses the Rtf format to show the test. The XMLViewer will
* convert the Xml to Rtf with some formats specified in the XMLViewerSettings,
* and then set the Rtf property to the value.
*
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
* All other rights reserved.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
using System;
using System.Text;
using System.Xml.Linq;
using System.Drawing;
namespace CSRichTextBoxSyntaxHighlighting
{
public class XMLViewer : System.Windows.Forms.RichTextBox
{
private XMLViewerSettings settings;
/// <summary>
/// The format settings.
/// </summary>
public XMLViewerSettings Settings
{
get
{
if (settings == null)
{
settings = new XMLViewerSettings
{
AttributeKey = Color.Red,
AttributeValue = Color.Blue,
Tag = Color.Blue,
Element = Color.DarkRed,
Value = Color.Black,
};
}
return settings;
}
set
{
settings = value;
}
}
/// <summary>
/// Convert the Xml to Rtf with some formats specified in the XMLViewerSettings,
/// and then set the Rtf property to the value.
/// </summary>
/// <param name="includeDeclaration">
/// Specify whether include the declaration.
/// </param>
public void Process(bool includeDeclaration)
{
try
{
// The Rtf contains 2 parts, header and content. The colortbl is a part of
// the header, and the {1} will be replaced with the content.
string rtfFormat = @"{{\rtf1\ansi\ansicpg1252\deff0\deflang1033\deflangfe2052
{{\fonttbl{{\f0\fnil Courier New;}}}}
{{\colortbl ;{0}}}
\viewkind4\uc1\pard\lang1033\f0
{1}}}";
// Get the XDocument from the Text property.
var xmlDoc = XDocument.Parse(this.Text, LoadOptions.None);
StringBuilder xmlRtfContent = new StringBuilder();
// If includeDeclaration is true and the XDocument has declaration,
// then add the declaration to the content.
if (includeDeclaration && xmlDoc.Declaration != null)
{
// The constants in XMLViewerSettings are used to specify the order
// in colortbl of the Rtf.
xmlRtfContent.AppendFormat(@"
\cf{0} <?\cf{1} xml \cf{2} version\cf{0} =\cf0 ""\cf{3} {4}\cf0 ""
\cf{2} encoding\cf{0} =\cf0 ""\cf{3} {5}\cf0 ""\cf{0} ?>\par",
XMLViewerSettings.TagID,
XMLViewerSettings.ElementID,
XMLViewerSettings.AttributeKeyID,
XMLViewerSettings.AttributeValueID,
xmlDoc.Declaration.Version,
xmlDoc.Declaration.Encoding);
}
// Get the Rtf of the root element.
string rootRtfContent = ProcessElement(xmlDoc.Root, 0);
xmlRtfContent.Append(rootRtfContent);
// Construct the completed Rtf, and set the Rtf property to this value.
this.Rtf = string.Format(rtfFormat, Settings.ToRtfFormatString(),
xmlRtfContent.ToString());
}
catch (System.Xml.XmlException xmlException)
{
throw new ApplicationException(
"Please check the input Xml. Error:" + xmlException.Message,
xmlException);
}
catch
{
throw;
}
}
// Get the Rtf of the xml element.
private string ProcessElement(XElement element, int level)
{
// This viewer does not support the Xml file that has Namespace.
if (!string.IsNullOrEmpty(element.Name.Namespace.NamespaceName))
{
throw new ApplicationException(
"This viewer does not support the Xml file that has Namespace.");
}
string elementRtfFormat = string.Empty;
StringBuilder childElementsRtfContent = new StringBuilder();
StringBuilder attributesRtfContent = new StringBuilder();
// Construct the indent.
string indent = new string(' ', 4 * level);
// If the element has child elements or value, then add the element to the
// Rtf. {{0}} will be replaced with the attributes and {{1}} will be replaced
// with the child elements or value.
if (element.HasElements || !string.IsNullOrWhiteSpace(element.Value))
{
elementRtfFormat = string.Format(@"
{0}\cf{1} <\cf{2} {3}{{0}}\cf{1} >\par
{{1}}
{0}\cf{1} </\cf{2} {3}\cf{1} >\par",
indent,
XMLViewerSettings.TagID,
XMLViewerSettings.ElementID,
element.Name);
// Construct the Rtf of child elements.
if (element.HasElements)
{
foreach (var childElement in element.Elements())
{
string childElementRtfContent =
ProcessElement(childElement, level + 1);
childElementsRtfContent.Append(childElementRtfContent);
}
}
// If !string.IsNullOrWhiteSpace(element.Value), then construct the Rtf
// of the value.
else
{
childElementsRtfContent.AppendFormat(@"{0}\cf{1} {2}\par",
new string(' ', 4 * (level + 1)),
XMLViewerSettings.ValueID,
CharacterEncoder.Encode(element.Value.Trim()));
}
}
// This element only has attributes. {{0}} will be replaced with the attributes.
else
{
elementRtfFormat =
string.Format(@"
{0}\cf{1} <\cf{2} {3}{{0}}\cf{1} />\par",
indent,
XMLViewerSettings.TagID,
XMLViewerSettings.ElementID,
element.Name);
}
// Construct the Rtf of the attributes.
if (element.HasAttributes)
{
foreach (XAttribute attribute in element.Attributes())
{
string attributeRtfContent = string.Format(
@" \cf{0} {3}\cf{1} =\cf0 ""\cf{2} {4}\cf0 """,
XMLViewerSettings.AttributeKeyID,
XMLViewerSettings.TagID,
XMLViewerSettings.AttributeValueID,
attribute.Name,
CharacterEncoder.Encode(attribute.Value));
attributesRtfContent.Append(attributeRtfContent);
}
attributesRtfContent.Append(" ");
}
return string.Format(elementRtfFormat, attributesRtfContent,
childElementsRtfContent);
}
}
}