Декодировать раздел CDATA в C # - PullRequest
11 голосов
/ 06 августа 2009

У меня есть немного 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 вне его, похоже, он вернется таким же образом.

Ответы [ 5 ]

17 голосов
/ 06 августа 2009

Вы можете использовать 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 возвращает значительные пробелы.

9 голосов
/ 30 августа 2011

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

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

string finalData = cDataNode.Data;
9 голосов
/ 07 мая 2010

На самом деле я думаю, что это довольно просто. в разделе 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

4 голосов
/ 11 января 2017

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

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

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

3 голосов
/ 06 августа 2009

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

...