XmlSerializer.Deserialize - проблема со смешанным содержимым (mixed content)
Всем привет.
Хочу десериализовать следующую строку:
<summary>
Initializes a new instance of the <see cref="T:PrimarkPOSAutoTests.WinAppDriver"/> class.
</summary>
Падает на этой строке со следующим исключением:
XmlException: 'Element' is an invalid XmlNodeType.
Хочу десериализовать эту строку как сплошной string. Можно ли так сделать? Или сериализатор путается из-за тэга <see/>?
P.S. Поле для хранения этого текста:
[XmlElement(ElementName = "summary")]
public string Summary { get; set; }
Ответы (1 шт):
Для начала, надо понять, что содержимое тэга <summary> - это не строка! Это структурированный текст, который должен быть представлен в виде фрагмента DOM.
Простейший способ считать его - это сделать свойство типа object:
[XmlElement(ElementName = "summary")]
public object Summary { get; set; } // реальный тип - XmlNode[]
Теперь в свойство Summary попадёт массив XmlNode[] из трёх узлов - XmlText, XmlElement и снова XmlText.
Однако, работать с таким нетипизированным полем неудобно, поэтому можно попытаться добавить больше типизации. К сожалению, просто поставить XmlNode[] в качестве типа не получится, а значит нужен отдельный класс:
[XmlElement(ElementName = "summary")]
public Summary Summary { get; set; }
public class Summary
{
[XmlAnyElement, XmlText]
public XmlNode[] Nodes { get; set; }
}
Если вы не желаете работать с DOM - можно завести свои типы для десериализации:
public class Summary
{
[XmlElement("see", Type = typeof(See))]
[XmlText(Type = typeof(string))]
public object[] Nodes { get; set; } // реальный тип - (See | string)[]
}
public class See
{
[XmlAttribute("cref")]
public string CRef { get; set; }
}
Наконец, если вам обязательно требуется получить именно строковое представление - можно сделать вот так:
[XmlElement("summary")]
public RawXml Summary { get; set; }
public class RawXml : IXmlSerializable
{
public string Content { get; set; }
XmlSchema IXmlSerializable.GetSchema() => null;
void IXmlSerializable.ReadXml(XmlReader reader)
{
Content = reader.ReadInnerXml();
}
void IXmlSerializable.WriteXml(XmlWriter writer)
{
writer.WriteRaw(Content);
}
}
Но без нужды так лучше не делать: вы рискуете запутаться в префиксах и пространствах имён.