33// See the LICENSE file in the project root for more information.
44
55using System ;
6- using System . Collections ;
76using System . Collections . Generic ;
87using System . Linq ;
9- using System . Reflection ;
10-
11- #if WINDOWS_UWP
12-
13- #endif
8+ using System . Xml ;
149
1510namespace Microsoft . Toolkit . Uwp . Notifications
1611{
1712 internal static class XmlWriterHelper
1813 {
19- public static void Write ( System . Xml . XmlWriter writer , object element )
14+ public static void Write ( XmlWriter writer , object element )
2015 {
2116 // If it isn't an XML element, don't write anything
2217 if ( element is not IHaveXmlName xmlElement )
@@ -26,56 +21,7 @@ public static void Write(System.Xml.XmlWriter writer, object element)
2621
2722 writer . WriteStartElement ( xmlElement . Name ) ;
2823
29- IEnumerable < PropertyInfo > properties = GetProperties ( element . GetType ( ) ) ;
30-
31- List < object > elements = new List < object > ( ) ;
32- object content = null ;
33-
34- // Write the attributes first
35- foreach ( PropertyInfo p in properties )
36- {
37- IEnumerable < Attribute > attributes = GetCustomAttributes ( p ) ;
38-
39- NotificationXmlAttributeAttribute attr = attributes . OfType < NotificationXmlAttributeAttribute > ( ) . FirstOrDefault ( ) ;
40-
41- object propertyValue = GetPropertyValue ( p , element ) ;
42-
43- // If it's the additional properties item
44- if ( p . Name == nameof ( IHaveXmlAdditionalProperties . AdditionalProperties ) && element is IHaveXmlAdditionalProperties && p . PropertyType == typeof ( IReadOnlyDictionary < string , string > ) )
45- {
46- continue ;
47- }
48-
49- // If it's an attribute
50- else if ( attr != null )
51- {
52- continue ;
53- }
54-
55- // If it's a content attribute
56- else if ( attributes . OfType < NotificationXmlContentAttribute > ( ) . Any ( ) )
57- {
58- continue ;
59- }
60- else if ( p . Name == nameof ( IHaveXmlChildren . Children ) && element is IHaveXmlChildren && p . PropertyType == typeof ( IEnumerable < object > ) )
61- {
62- continue ;
63- }
64-
65- // Otherwise it's an element or collection of elements
66- else
67- {
68- continue ;
69- }
70- }
71-
72- content = ( element as IHaveXmlText ) ? . Text ;
73-
74- foreach ( var property in ( element as IHaveXmlAdditionalProperties ) ? . AdditionalProperties ?? Enumerable . Empty < KeyValuePair < string , string > > ( ) )
75- {
76- writer . WriteAttributeString ( property . Key , property . Value ) ;
77- }
78-
24+ // Write all named properties
7925 foreach ( var property in ( element as IHaveXmlNamedProperties ) ? . EnumerateNamedProperties ( ) ?? Enumerable . Empty < KeyValuePair < string , object > > ( ) )
8026 {
8127 if ( property . Value is not null )
@@ -84,123 +30,37 @@ public static void Write(System.Xml.XmlWriter writer, object element)
8430 }
8531 }
8632
87- foreach ( var child in ( element as IHaveXmlChildren ) ? . Children ?? Enumerable . Empty < object > ( ) )
33+ // Write all additional properties
34+ foreach ( var property in ( element as IHaveXmlAdditionalProperties ) ? . AdditionalProperties ?? Enumerable . Empty < KeyValuePair < string , string > > ( ) )
8835 {
89- elements . Add ( child ) ;
36+ writer . WriteAttributeString ( property . Key , property . Value ) ;
9037 }
9138
92- // Then write children
93- foreach ( object el in elements )
39+ // Write the inner text, if any
40+ if ( ( element as IHaveXmlText ) ? . Text is string { Length : > 0 } text )
9441 {
95- // Otherwise just write the single element
96- Write ( writer , el ) ;
42+ writer . WriteString ( text ) ;
9743 }
9844
99- // Then write any content if there is content
100- if ( content != null )
45+ // Write all children, if any
46+ foreach ( var child in ( element as IHaveXmlChildren ) ? . Children ?? Enumerable . Empty < object > ( ) )
10147 {
102- string contentString = content . ToString ( ) ;
103- if ( ! string . IsNullOrWhiteSpace ( contentString ) )
104- {
105- writer . WriteString ( contentString ) ;
106- }
48+ Write ( writer , child ) ;
10749 }
10850
10951 writer . WriteEndElement ( ) ;
11052 }
11153
112- private static object GetPropertyValue ( PropertyInfo propertyInfo , object obj )
113- {
114- #if NETFX_CORE
115- return propertyInfo . GetValue ( obj ) ;
116- #else
117- return propertyInfo . GetValue ( obj , null ) ;
118- #endif
119- }
120-
12154 private static string PropertyValueToString ( object propertyValue )
12255 {
123- Type type = propertyValue . GetType ( ) ;
124-
125- if ( IsEnum ( type ) )
126- {
127- EnumStringAttribute enumStringAttr = GetEnumStringAttribute ( propertyValue as Enum ) ;
128-
129- if ( enumStringAttr != null )
130- {
131- return enumStringAttr . String ;
132- }
133- }
134- else if ( propertyValue is bool )
135- {
136- if ( ( bool ) propertyValue )
137- {
138- return "true" ;
139- }
140-
141- return "false" ;
142- }
143- else if ( propertyValue is DateTimeOffset ? )
144- {
145- DateTimeOffset ? dateTime = propertyValue as DateTimeOffset ? ;
146- if ( dateTime . HasValue )
147- {
148- // ISO 8601 format
149- return System . Xml . XmlConvert . ToString ( dateTime . Value ) ;
150- }
151- else
152- {
153- return null ;
154- }
155- }
156-
157- return propertyValue . ToString ( ) ;
158- }
159-
160- private static EnumStringAttribute GetEnumStringAttribute ( Enum enumValue )
161- {
162- #if NETFX_CORE
163- return enumValue . GetType ( ) . GetTypeInfo ( ) . GetDeclaredField ( enumValue . ToString ( ) ) . GetCustomAttribute < EnumStringAttribute > ( ) ;
164- #else
165- MemberInfo [ ] memberInfo = enumValue . GetType ( ) . GetMember ( enumValue . ToString ( ) ) ;
166-
167- if ( memberInfo != null && memberInfo . Length > 0 )
56+ return propertyValue switch
16857 {
169- object [ ] attrs = memberInfo [ 0 ] . GetCustomAttributes ( typeof ( EnumStringAttribute ) , false ) ;
170-
171- if ( attrs != null && attrs . Length > 0 )
172- return attrs [ 0 ] as EnumStringAttribute ;
173- }
174-
175- return null ;
176- #endif
177- }
178-
179- private static bool IsEnum ( Type type )
180- {
181- #if NETFX_CORE
182- return type . GetTypeInfo ( ) . IsEnum ;
183- #else
184- return type . IsEnum ;
185- #endif
186- }
187-
188- private static IEnumerable < PropertyInfo > GetProperties ( Type type )
189- {
190- #if NETFX_CORE
191- return type . GetTypeInfo ( ) . DeclaredProperties ;
192- #else
193- return type . GetProperties ( ) ;
194- #endif
195- }
196-
197- private static IEnumerable < Attribute > GetCustomAttributes ( PropertyInfo propertyInfo )
198- {
199- #if NETFX_CORE
200- return propertyInfo . GetCustomAttributes ( ) ;
201- #else
202- return propertyInfo . GetCustomAttributes ( true ) . OfType < Attribute > ( ) ;
203- #endif
58+ true => "true" ,
59+ false => "false" ,
60+ DateTimeOffset dateTime => XmlConvert . ToString ( dateTime ) , // ISO 8601 format
61+ { } value => value . ToString ( ) ,
62+ _ => null
63+ } ;
20464 }
20565
20666 /// <summary>
0 commit comments