Декодировать секцию CDATA в С#

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

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

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

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

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

Ответ 1

Вы можете использовать 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+", " ");

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

Ответ 2

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

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

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

Спасибо
XOnDaRocks

Ответ 3

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

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

string finalData = cDataNode.Data;

Ответ 4

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

Ответ 5

Простейшая форма решения Фрэнки:

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

Свойство Value эквивалентно свойству Data типа cast XmlCDataSection.