The previous case encountered a scene about XML serialization while writing Linq2douban. When you add and update data through the Douban API, you need to post an XML entry, such as:
Add activity (part of the XML with percent% is the part that needs to be filled in, in order to streamline the deletion of xmlns)
01 <?xml version="1.0" encoding="UTF-8"?>
02 <entry>
03 <title>%title%</title>
04 <category scheme="http://www.douban.com/2007#kind" term="http://www.douban.com/2007#%Category%"/>
05 <content>%Content%</content>
06
07 <db:attribute name="invite_only">%IsInviteOnly%</db:attribute>
08 <db:attribute name="can_invite">%CanInvite%</db:attribute>
09 <gd:when endTime="%Duration.End%" startTime="%Duration.Start%"/>
10 <gd:where valueString="%Where%"/>
11 </entry>
There are two methods that can be thought of at once--implemented by XmlSerializer or by implementing the IXmlSerializable interface on the entity class--but soon discovered that there were several problems that could not be resolved:
1. XmlSerializer does not support serialization of generic sets, and I used a lot of IList and IDictionary to define entity class, as Db:attribute I defined as IDictionary
2, XmlSerializer can only generate complete element and attribute, like the above section of XML <category> node term attribute changes in only the back of the%category% section, which can not generate
3, there is the addition and update of the post content is different, which means that the same entity class, there are many serialization scenarios
4, Douban XML entry format may change, and I do not want to change the code so
Think about it, the best way is through the XML template + reflection (for short, XML template replacement) to generate, as the above XML etnry inside the percent of the part, replace it, this can solve the above four problems. In addition to providing the same serialization as the XmlSerializer feature, XML template substitution satisfies the following requirements:
1, you can serialize the implementation of IEnumerable collection, which is the most common set, of course, most of the generic set is also applied IEnumerable
2, to provide more flexible replacement. The serialization order implemented by XmlSerializer is "A (b (c) b) A", and serialization of child objects can only be nested patterns, while XML template substitution can achieve any level of substitution.
3. Provide common serialization for each type of object without any definition of attribute and no need to modify the definition of the object. For a given object and XML template, XML content is generated by the launch of the property value for XML substitution, and for the same object, different XML templates can be generated.
4, modify the serialization result by modifying the XML template
The following is a modified RSS XML template, which is designed to implement the template replacement at the end, and to complete a helper class that code4fun the above functionality.
A special place:
1, <category> node: through "." Can access the properties of the child object, if you want to get the length of Domain can be written as "%category.domain.length%"
2, <noReplacement> node: This node does not contain any replacement information, when the replacement processing should be ignored
3, <skipHours> node: skiphours is a list<int> set, we want to be able to expand multiple
4, <as:scope> node:<scope> is the template definition, Declaration <scope> node contained within the scope of the Channel.items object, all percent% (excluding%./category.name %) are property access to the Items object. Since the items object here is a list<rssitem> collection, multiple <item> loops are generated. The meaning of scope is similar to the program domain, which supports multiple scope nesting, and the scope definition does not appear in the last generated XML.