annotate HowTo/Mapping/MapToJson.cs @ 1:8f65451dc28f

Исправлена проблема с фабрикой и выборкой нескольких объектов в linq выражении
author cin
date Fri, 28 Mar 2014 01:04:56 +0400
parents f990fcb411a9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1 using System;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2 using System.Globalization;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
3 using System.Text;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
4 using System.Xml;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
5
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
6 using NUnit.Framework;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
7
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
8 using BLToolkit.Mapping;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
9 using BLToolkit.Reflection;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
10
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
11 namespace HowTo.Mapping
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
12 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
13 public class JsonMapper : MapDataDestinationBase, IMapDataDestinationList, ISupportMapping
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
14 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
15 private static readonly long InitialJavaScriptDateTicks = new DateTime(1970, 1, 1).Ticks;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
16
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
17 private string[] _fieldNames;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
18 private readonly StringBuilder _sb;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
19 private MappingSchema _mappingSchema;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
20 private bool _scalar;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
21 private bool _first;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
22 private bool _firstElement;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
23 private int _indent;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
24
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
25 public JsonMapper() : this(new StringBuilder(), 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
26 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
27 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
28
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
29 public JsonMapper(StringBuilder sb) : this(sb, 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
30 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
31 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
32
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
33 public JsonMapper(StringBuilder sb, int indent)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
34 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
35 _sb = sb;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
36 _indent = indent;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
37 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
38
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
39 public override Type GetFieldType(int index)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
40 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
41 // Same as typeof(object)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
42 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
43 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
44 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
45
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
46 public override int GetOrdinal(string name)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
47 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
48 return Array.IndexOf(_fieldNames, name);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
49 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
50
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
51 public override void SetValue(object o, int index, object value)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
52 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
53 SetValue(o, _fieldNames[index], value);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
54 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
55
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
56 public override void SetValue(object o, string name, object value)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
57 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
58 if (!_scalar)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
59 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
60 // Do not Json null values until it's an array
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
61 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
62 if (value == null || (value is XmlNode && IsEmptyNode((XmlNode)value)))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
63 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
64
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
65 if (_first)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
66 _first = false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
67 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
68 _sb
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
69 .Append(',')
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
70 .AppendLine()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
71 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
72
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
73 for (int i = 0; i < _indent; ++i)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
74 _sb.Append(' ');
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
75
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
76 _sb
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
77 .Append('"')
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
78 .Append(name)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
79 .Append("\":")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
80 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
81 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
82
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
83 if (value == null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
84 _sb.Append("null");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
85 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
86 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
87 switch (Type.GetTypeCode(value.GetType()))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
88 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
89 case TypeCode.Empty:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
90 case TypeCode.DBNull:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
91 _sb.Append("null");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
92 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
93 case TypeCode.Boolean:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
94 _sb.Append((bool)value? "true": "false");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
95 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
96 case TypeCode.Char:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
97 _sb
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
98 .Append('\'')
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
99 .Append((char)value)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
100 .Append('\'')
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
101 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
102 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
103 case TypeCode.SByte:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
104 case TypeCode.Int16:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
105 case TypeCode.Int32:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
106 case TypeCode.Int64:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
107 case TypeCode.Byte:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
108 case TypeCode.UInt16:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
109 case TypeCode.UInt32:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
110 case TypeCode.UInt64:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
111 case TypeCode.Single:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
112 case TypeCode.Double:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
113 case TypeCode.Decimal:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
114 _sb.Append(((IFormattable)value).ToString(null, CultureInfo.InvariantCulture));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
115 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
116 case TypeCode.DateTime:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
117 _sb
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
118 .Append("new Date(")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
119 .Append((((DateTime)value).Ticks - InitialJavaScriptDateTicks)/10000)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
120 .Append(")");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
121 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
122 case TypeCode.String:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
123 _sb
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
124 .Append('"')
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
125 .Append(encode((string)value))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
126 .Append('"')
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
127 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
128 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
129 default:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
130 if (value is XmlNode)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
131 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
132 if (IsEmptyNode((XmlNode) value))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
133 _sb.Append("null");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
134 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
135 WriteXmlJson((XmlNode)value);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
136 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
137 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
138 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
139 JsonMapper inner = new JsonMapper(_sb, _indent + 1);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
140
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
141 if (value.GetType().IsArray)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
142 _mappingSchema.MapSourceListToDestinationList(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
143 _mappingSchema.GetDataSourceList(value), inner);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
144 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
145 _mappingSchema.MapSourceToDestination(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
146 _mappingSchema.GetDataSource(value), value, inner, inner);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
147 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
148 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
149 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
150 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
151 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
152
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
153 private static string encode(string value)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
154 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
155 return value.Replace("\r\n", "\\r")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
156 .Replace("\n\r", "\\r")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
157 .Replace("\n", "\\r")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
158 .Replace("\r", "\\r")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
159 .Replace("\"","\\\"");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
160 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
161
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
162 private void WriteXmlJson(XmlNode node)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
163 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
164 XmlNode textNode = GetTextNode(node);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
165 if (textNode != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
166 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
167 _sb
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
168 .Append("\"")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
169 .Append(encode(textNode.Value))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
170 .Append('\"')
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
171 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
172 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
173 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
174 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
175
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
176 bool first = true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
177
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
178 _sb.Append('{');
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
179
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
180 if (node.Attributes != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
181 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
182 foreach (XmlAttribute attr in node.Attributes)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
183 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
184 if (first)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
185 first = false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
186 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
187 _sb.Append(',');
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
188
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
189 _sb
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
190 .Append("\"@")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
191 .Append(attr.Name)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
192 .Append("\":\"")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
193 .Append(encode(attr.Value))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
194 .Append('\"')
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
195 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
196 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
197 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
198
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
199 foreach (XmlNode child in node.ChildNodes)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
200 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
201 if (IsWhitespace(child) || IsEmptyNode(child))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
202 continue;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
203
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
204 if (first)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
205 first = false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
206 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
207 _sb.Append(',');
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
208
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
209 if (child is XmlText)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
210 _sb
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
211 .Append("\"#text\":\"")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
212 .Append(encode(child.Value))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
213 .Append('\"')
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
214 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
215 else if (child is XmlElement)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
216 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
217 _sb
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
218 .Append('"')
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
219 .Append(child.Name)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
220 .Append("\":")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
221 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
222 WriteXmlJson(child);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
223 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
224 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
225 System.Diagnostics.Debug.Fail("Unexpected node type " + child.GetType().FullName);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
226 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
227 _sb.Append('}');
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
228 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
229 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
230
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
231 private static bool IsWhitespace(XmlNode node)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
232 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
233 switch (node.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
234 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
235 case XmlNodeType.Comment:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
236 case XmlNodeType.Whitespace:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
237 case XmlNodeType.SignificantWhitespace:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
238 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
239 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
240 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
241 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
242
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
243 private static bool IsEmptyNode(XmlNode node)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
244 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
245 if (node.Attributes != null && node.Attributes.Count > 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
246 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
247
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
248 if (node.HasChildNodes)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
249 foreach (XmlNode childNode in node.ChildNodes)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
250 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
251 if (IsWhitespace(childNode) || IsEmptyNode(childNode))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
252 continue;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
253
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
254 // Not a whitespace, nor inner empty node.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
255 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
256 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
257 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
258
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
259 return node.Value == null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
260 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
261
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
262 private static XmlNode GetTextNode(XmlNode node)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
263 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
264 if (node.Attributes != null && node.Attributes.Count > 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
265 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
266
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
267 XmlNode textNode = null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
268
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
269 foreach (XmlNode childNode in node.ChildNodes)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
270 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
271 // Ignore all whitespace.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
272 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
273 if (IsWhitespace(childNode))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
274 continue;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
275
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
276 if (childNode is XmlText)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
277 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
278 // More then one text node.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
279 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
280 if (textNode != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
281 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
282
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
283 // First text node.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
284 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
285 textNode = childNode;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
286 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
287 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
288 // Not a text node - break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
289 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
290 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
291 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
292
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
293 return textNode;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
294 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
295
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
296 #region ISupportMapping Members
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
297
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
298 void ISupportMapping.BeginMapping(InitContext initContext)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
299 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
300 _first = true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
301 _mappingSchema = initContext.MappingSchema;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
302 _fieldNames = new string[initContext.DataSource.Count];
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
303
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
304 for (int i = 0; i < _fieldNames.Length; ++i)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
305 _fieldNames[i] = initContext.DataSource.GetName(i);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
306
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
307 _scalar = _fieldNames.Length == 1 && string.IsNullOrEmpty(_fieldNames[0]);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
308
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
309 if (_scalar)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
310 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
311
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
312 if (_fieldNames.Length <= 1)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
313 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
314 // Reset the indent since output is a single line.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
315 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
316 _indent = 0;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
317 _sb.Append('{');
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
318 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
319 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
320 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
321 if (_indent > 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
322 _sb.AppendLine();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
323
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
324 for (int i = 0; i < _indent; ++i)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
325 _sb.Append(' ');
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
326
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
327 _sb
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
328 .Append('{')
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
329 .AppendLine()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
330 ;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
331 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
332 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
333
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
334 void ISupportMapping.EndMapping(InitContext initContext)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
335 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
336 if (_scalar)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
337 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
338
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
339 if (_fieldNames.Length > 1)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
340 _sb.AppendLine();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
341
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
342 for (int i = 0; i < _indent; ++i)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
343 _sb.Append(' ');
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
344 _sb.Append('}');
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
345 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
346
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
347 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
348
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
349 #region IMapDataDestinationList Members
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
350
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
351 void IMapDataDestinationList.InitMapping(InitContext initContext)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
352 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
353 _firstElement = true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
354 _sb.Append('[');
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
355 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
356
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
357 IMapDataDestination IMapDataDestinationList.GetDataDestination(InitContext initContext)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
358 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
359 return this;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
360 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
361
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
362 object IMapDataDestinationList.GetNextObject(InitContext initContext)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
363 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
364 if (_firstElement)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
365 _firstElement = false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
366 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
367 _sb.Append(',');
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
368
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
369 return this;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
370 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
371
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
372 void IMapDataDestinationList.EndMapping(InitContext initContext)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
373 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
374 _sb.Append(']');
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
375 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
376
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
377 #endregion
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
378
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
379 public override string ToString()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
380 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
381 return _sb.ToString();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
382 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
383 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
384
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
385 [TestFixture]
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
386 public class MapToJson
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
387 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
388 public class Inner
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
389 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
390 public string Name = "inner \"object \n name";
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
391 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
392
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
393 public class Inner2
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
394 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
395 public string Name;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
396 public int Value;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
397 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
398
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
399 public class SourceObject
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
400 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
401 public string Foo = "Foo";
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
402 public double Bar = 1.23;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
403 public DateTime Baz = DateTime.Today;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
404 [MapIgnore(false)]
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
405 public Inner Inner = new Inner();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
406 [MapIgnore(false)]
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
407 public Inner2 Inner2 = new Inner2();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
408 public string[] StrArray = {"One", "Two", "Three"};
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
409 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
410
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
411 [Test]
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
412 public void Test()
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
413 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
414 JsonMapper jm = new JsonMapper(new StringBuilder(256));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
415
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
416 Map./*[a]*/MapSourceToDestination/*[/a]*/(Map.GetObjectMapper(typeof(SourceObject)), new SourceObject(), jm, jm);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
417 Console.Write(jm.ToString());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
418
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
419 // Expected output:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
420 //
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
421 // {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
422 // "Foo":"Foo",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
423 // "Bar":1.23,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
424 // "Baz":new Date(11823840000000000),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
425 // "Inner":{ "Name":"inner \"object \r name"},
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
426 // "Inner2":
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
427 // {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
428 // "Name":null,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
429 // "Value":0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
430 // },
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
431 // "StrArray":["One","Two","Three"]
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
432 // }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
433 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
434 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
435 }