Декодируйте раздел CDATA в C#

у меня есть немного XML следующим образом:

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

Я получаю доступ к нему с помощью curXmlNode.SelectSingleNode("description").InnerText но возвращает значение

rn      This is a "description"rn      that I have formatted
вместо
This is a "description" that I have formatted.

есть ли простой способ получить такой вывод из раздела CDATA? Оставляя фактический тег CDATA, похоже, он возвращается таким же образом.

5 ответов


Вы можете использовать Linq для чтения CDATA.

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

очень легко получить значение таким образом.

вот хороший обзор на MSDN:http://msdn.microsoft.com/en-us/library/bb308960.aspx

для .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+", " ");

который обрезает значение узла, заменяет новые строки пустыми и заменяет 1+ пробелы одним пробелом. Я не думаю, что есть любой другой способ сделать это, учитывая CDATA возвращает значительные пробелы.


Я думаю, что лучший путь...

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

string finalData = cDataNode.Data;

На самом деле я думаю, что это довольно просто. the CDATA раздел будет загружен в XmlDocument как другой XmlNode разница в том, что этот узел будет иметь свойство NodeType = CDATA, что означает, если у вас есть XmlNode node = doc.SelectSingleNode("section/description"); этот узел будет иметь ChildNode С InnerText свойство заполнило чистые данные, и вы хотите удалить особые символы, просто используйте Trim() и у вас будут данные.

код будет выглядеть как

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

спасибо
XOnDaRocks


более простая форма @Фрэнки:

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

на Value свойства эквивалентно до Data свойство casted XmlCDataSection тип.


блоки CDATA эффективно дословно. Любые пробелы внутри CDATA значимы, по определению, в соответствии со спецификацией XML. Таким образом, вы получаете этот пробел при получении значения узла. Если вы хотите удалить его, используя свои собственные правила (поскольку спецификация XML не указывает стандартный способ удаления пробелов в CDATA), вы должны сделать это самостоятельно, используя String.Replace, Regex.Replace etc по мере необходимости.