在 C# 中解码 CDATA 部分

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1236785/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 14:02:24  来源:igfitidea点击:

Decode CDATA section in C#

c#.netxmlxmldocumentcdata

提问by Jess

I have a bit of XML as follows:

我有一些 XML 如下:

<section>
  <description>
    <![CDATA[
      This is a "description"
      that I have formatted
    ]]>
  </description>
</section>

I'm accessing it using curXmlNode.SelectSingleNode("description").InnerTextbut the value returns

我正在使用它访问它,curXmlNode.SelectSingleNode("description").InnerText但值返回

\r\n      This is a "description"\r\n      that I have formatted
代替
This is a "description" that I have formatted.

Is there a simple way to get that sort of output from a CDATA section? Leaving the actual CDATA tag out seems to have it return the same way.

有没有一种简单的方法可以从 CDATA 部分获得那种输出?离开实际的 CDATA 标签似乎让它以同样的方式返回。

采纳答案by Jim Schubert

You can use Linq to read CDATA.

您可以使用 Linq 读取 CDATA。

XDocument xdoc = XDocument.Load("YourXml.xml");
xDoc.DescendantNodes().OfType<XCData>().Count();

It's very easy to get the Value this way.

通过这种方式获取 Value 非常容易。

Here's a good overview on MSDN: http://msdn.microsoft.com/en-us/library/bb308960.aspx

这是 MSDN 上的一个很好的概述:http: //msdn.microsoft.com/en-us/library/bb308960.aspx

for .NET 2.0, you probably just have to pass it through Regex:

对于 .NET 2.0,您可能只需要通过 Regex 传递它:

     string xml = @"<section>
                      <description>
                        <![CDATA[
                          This is a ""description""
                          that I have formatted
                        ]]>
                      </description>
                    </section>";

        XPathDocument xDoc = new XPathDocument(new StringReader(xml.Trim()));
        XPathNavigator nav = xDoc.CreateNavigator();
        XPathNavigator descriptionNode = 
            nav.SelectSingleNode("/section/description");

        string desiredValue = 
            Regex.Replace(descriptionNode.Value
                                     .Replace(Environment.NewLine, String.Empty)
                                     .Trim(),
                @"\s+", " ");

that trims your node value, replaces newlines with empty, and replaces 1+ whitespaces with one space. I don't think there's any other way to do it, considering the CDATA is returning significant whitespace.

修剪您的节点值,用空替换换行符,用一个空格替换 1+ 个空格。考虑到 CDATA 返回大量空白,我认为没有其他方法可以做到这一点。

回答by Pavel Minaev

CDATA blocks are effectively verbatim. Any whitespace inside CDATA is significant, by definition, according to XML spec. Therefore, you get that whitespace when you retrieve the node value. If you want to strip it using your own rules (since XML spec doesn't specify any standard way of stripping whitespace in CDATA), you have to do it yourself, using String.Replace, Regex.Replaceetc as needed.

CDATA 块实际上是逐字逐句的。根据 XML 规范,根据定义,CDATA 中的任何空白都是重要的。因此,当您检索节点值时,您会得到该空格。如果你想用你自己的规则(因为XML规范没有指定CDATA剥离空白的任何标准方式)剥离它,你必须自己做,使用String.ReplaceRegex.Replace需要等。

回答by XOnDaRocks

Actually i think is pretty much simple. the CDATAsection it will be loaded in the XmlDocumentlike another XmlNodethe difference is that this node is going to has the property NodeType = CDATA, wich it mean if you have the XmlNode node = doc.SelectSingleNode("section/description");that node will have a ChildNodewith the InnerTextproperty filled the pure data, and there is you want to remove the especial characters just use Trim()and you will have the data.

其实我觉得很简单。该CDATA会在加载部分XmlDocument像另一个XmlNode不同的是,这个节点将要拥有财产的NodeType = CDATA,至极意思,如果你有XmlNode node = doc.SelectSingleNode("section/description");该节点将有一个ChildNodeInnerText属性充满了纯粹的数据,并有你想要删除刚刚使用的特殊字符Trim(),您将拥有数据。

The code will look like

代码看起来像

XmlNode cDataNode = doc.SelectSingleNode("section/description").ChildNodes[0];
string finalData = cDataNode.InnerText.Trim();

Thanks
XOnDaRocks

感谢
XOnDaRocks

回答by Franky

I think the best way is...

我认为最好的方法是...

XmlCDataSection cDataNode = (XmlCDataSection)(doc.SelectSingleNode("section/description").ChildNodes[0]);

string finalData = cDataNode.Data;

回答by Arithmomaniac

A simpler form of @Franky's solution:

@Franky 解决方案的更简单形式:

doc.SelectSingleNode("section/description").FirstChild.Value

The Valueproperty is equivalentto the Dataproperty of the casted XmlCDataSectiontype.

Value属性等效Data强制转换XmlCDataSection类型的属性。