Реализация IXmlSerializable для контента, содержащего данные с или без тегов CDATA - PullRequest
0 голосов
/ 16 февраля 2010

Я пытаюсь найти способ анализа тега xml, в котором содержимое передается с тегами CDATA для некоторого ввода, но не для всех.

Например, ниже приведен пример содержимого, которое я получил бы для данных, содержащих теги CDATA. Но есть и другие сценарии, в которых теги CDATA опущены.

<Data><![CDATA[ <h1>CHAPTER 2<br/> EDUCATION</h1>
                <P>  Analysis paragraph  </P> ]]></Data>

Существует ли элегантный способ как-то обнаружить это и реализовать метод ReadXml, который может анализировать оба типа ввода (с CDATA или без него)? Пока что моя реализация ReadXml () выглядит следующим образом, но я получаю ошибки при разборе, когда тэг CDATA опущен.

    public void ReadXml(XmlReader reader)
    {
        bool isEmpty = reader.IsEmptyElement;
        reader.ReadStartElement();
        if (isEmpty)
        {
            _data = string.Empty;
        }
        else
        {                
            switch (reader.MoveToContent())
            {
                case XmlNodeType.Text:
                case XmlNodeType.CDATA:
                    _data = reader.ReadContentAsString();
                    break;
                default:
                    _data = string.Empty;
                    break;
            }
            reader.ReadEndElement();
        }                         
    }

1 Ответ

1 голос
/ 16 февраля 2010

Код ниже тестируется на следующих образцах:

<Data><h1>CHAPTER 2<br/> EDUCATION</h1><P>  Analysis paragraph  </P></Data>
<Data>test<h1>CHAPTER 2<br/> EDUCATION</h1><P>  Analysis paragraph  </P></Data>
<Data><![CDATA[ <h1>CHAPTER 2<br/> EDUCATION</h1><P>  Analysis paragraph  </P> ]]></Data>
<Data></Data>

Вместо этого я использую XPathNavigator, так как он позволяет вернуться назад.

public void ReadXml(XmlReader reader)
{
    XmlDocument doc = new XmlDocument {PreserveWhitespace = false};
    doc.Load(reader);

    var navigator = doc.CreateNavigator();
    navigator.MoveToChild(XPathNodeType.Element);
    _data = navigator.InnerXml.Trim().StartsWith("&lt;") ? navigator.Value : navigator.InnerXml;
}
...