- Хроники. - -
Сериализация Словаря (Dictionary) и XML CDATA.
Posted By Ikutsin On 5 июня 2008 @ 11:11 In .NET C# | Comments Disabled
Последней моей головной болью был элемент CDATA. По заданию нужно было учесть возможность, что в полях XML может присутствовать HTML разметка. А xml для десериализации портить нельзя, и эскейпинг тоже не подошел бы. Вот и было решено использовать блок CDATA [1].
Первыми граблями было отсутствие возможности создания CDATA при трансформации XSLT. Где-то читал, что если формат на выходе не XML:
то можно использовать тег
Хоть w3c предусматривает CDATA для элементов (добавлением аттрибутов cdata-section-elements в xsl:output):
это не работает когда пытаюсь вставить XML элементы.
Решением было сделать еще обработчик, уже с помощью кода:
foreach (XmlNode contentValue in ContentValues)
{
contentValue.InnerXml = doc.CreateCDataSection(contentValue.InnerXml).OuterXml;
}
Все бы хорошо, да вот как известно, System.Collections.Generic.Dictionary не сериализируется, по этому нужен свой класс сериализации. Его не составило проблемы найти, правда был у него один недостаток, не хотел он десиареализировать класс XmlCDataSection, возвращая null. Сериализация по умолчанию работала, значит необходимо было править код SerializableDictionary. Вот что получилось:
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;public class SerializableDictionary
: Dictionary , IXmlSerializable
{
public System.Xml.Schema.XmlSchema GetSchema()
{return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
XmlSerializer keySerializer = new [2] XmlSerializer(typeof [3](TKey));
XmlSerializer valueSerializer = new [2] XmlSerializer(typeof [3](TValue));bool wasEmpty = reader.IsEmptyElement;
reader.Read();if (wasEmpty) return;
while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
{
reader.ReadStartElement(«item»);reader.ReadStartElement(«key»);
TKey key = (TKey)keySerializer.Deserialize(reader);
reader.ReadEndElement();
reader.ReadStartElement(«value»);TValue value;
if (typeof [3](TValue) == typeof [3](XmlCDataSection))
{
var o = reader.Value;
value = (TValue) (object)(new [2] XmlDocument().CreateCDataSection(o));
reader.Read();
} else
{
value = (TValue)valueSerializer.Deserialize(reader);
}reader.ReadEndElement();
this.Add(key, value);
reader.ReadEndElement();
reader.MoveToContent();
}
reader.ReadEndElement();
}public void WriteXml(System.Xml.XmlWriter writer)
{
XmlSerializer keySerializer = (typeof [2](TKey));
XmlSerializer valueSerializer = (typeof(TValue));foreach (TKey key in this.Keys)
{
writer.WriteStartElement(«item»);
writer.WriteStartElement(«key»);
keySerializer.Serialize(writer, key);
writer.WriteEndElement();writer.WriteStartElement(«value»);
TValue value = this[key];
valueSerializer.Serialize(writer, value);
writer.WriteEndElement();writer.WriteEndElement();
}}
}
Теперь на выходе можно было получать html, который не был эскейпан и игнорировался обычными XML парсерами.
А достать содержимое можно так: Content.First().Value.Value;
Article printed from Хроники.:
URL to article: /60-serializaciya-slovarya-dictionary-i-xml-cdata
URLs in this post:
[1] CDATA: http://www.w3schools.com/XML/xml_cdata.asp
[2] new: http://www.google.com/search?q=new+msdn.microsoft.com
[3] typeof: http://www.google.com/search?q=typeof+msdn.microsoft.com
Click here to print.
Copyright © 2008 Все, что меня окружает. All rights reserved.