【问题标题】:Implementing IXmlSerializable for content containing data with or without CDATA tags为包含带或不带 CDATA 标记的数据的内容实现 IXmlSerializable
【发布时间】:2010-02-16 16:57:17
【问题描述】:

我正在尝试找出一种方法来解析 xml 标记,其中内容是通过 CDATA 标记传递的,用于某些输入,但不是全部。

例如,以下是我将收到的包含 CDATA 标记的数据的示例内容。但还有一些其他情况会省略 CDATA 标记。

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

是否有一种优雅的方法可以以某种方式检测到这一点,并实现可以解析两种类型的输入(带或不带 CDATA)的 ReadXml 方法?到目前为止,我的 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();
        }                         
    }

【问题讨论】:

  • 你能提供一个失败代码的例子吗?如果我将 nocdata 传递给您的 ReadXml 函数,它就可以正常工作。
  • 当标签没有 cdata 环绕标签时,它对我来说失败了。从我上面的示例中删除 CDATA 标签后,它确定对你有用吗?执行 reader.ReadEndElement()... 时出现错误
  • 我测试了一个更简单的。检查我的代码示例的答案。

标签: c# .net cdata ixmlserializable readxml


【解决方案1】:

以下代码在以下示例上进行了测试:

<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;
}

【讨论】:

  • 这确实可以解决问题。我最终使用 Xnode 而不是 XmlDocument,然后使用它的 createNavigator 方法来获取 XPathNavigator 用于检索 innerxml。
  • 使用 XmlNode 可能更好,并且很高兴它起作用了。随意将答案标记为已接受:)
  • 使用 XmlDocument.Load 然后获取 XmlNode 对我不起作用。我给出的示例中的示例 xml 只是实际输入数据中的节点之一(实际输入具有相当复杂的 xml 结构)。因此,如果我在解析此特定节点时尝试执行 XmlDocument.Load,则会出现错误,并且无法进一步阅读。
猜你喜欢
  • 2010-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多