2009-08-06 15 views
10

mam trochę XML w następujący sposób:Decode CDATA w C#

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

mam dostępu do niego za pomocą curXmlNode.SelectSingleNode("description").InnerText ale wartość zwraca

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

Czy istnieje prosty sposób, aby uzyskać tego rodzaju wyjście z sekcji CDATA? Pozostawienie rzeczywistego znacznika CDATA wydaje się mieć ten sam zwrot.

Odpowiedz

15

Możesz użyć Linq do odczytu CDATA.

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

Bardzo łatwo jest zdobyć wartość w ten sposób.

Oto dobry przegląd na MSDN: http://msdn.microsoft.com/en-us/library/bb308960.aspx

dla .NET 2.0, prawdopodobnie po prostu trzeba przekazać go przez 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+", " "); 

że przycina swoją wartość węzła, zastępuje znaki nowej linii z pusta, a zastępuje 1+ białe spacje jedną spacją. Nie sądzę, że jest jakikolwiek inny sposób, aby to zrobić, biorąc pod uwagę, że CDATA zwraca znaczące białe znaki.

+0

Dzięki, ale powinienem być bardziej szczegółowy, że robię to w wersji 2.0 na Compact Framework. Mogę się zastanowić, czy bardziej korzystne byłoby przejście do 3.5 w przyszłości. – Jess

+0

Edytowałem z innym pomysłem. Nie mam zainstalowanego .NET 2.0 CF, więc nie jestem w 100% pewny, czy jest kompatybilny. –

+0

Działa świetnie. Dzięki! – Jess

3

Bloki CDATA są praktycznie dosłowne. Wszelkie odstępy wewnątrz CDATA są z definicji znaczące, zgodnie ze specyfikacją XML. Dlatego uzyskujesz tę białą przestrzeń, gdy pobierzesz wartość węzła. Jeśli chcesz rozebrać go za pomocą własnych reguł (ponieważ specyfikacja XML nie określa żadnego standardowego sposobu usuwania białych znaków w CDATA), musisz to zrobić samodzielnie, używając w razie potrzeby String.Replace, Regex.Replace itd.

9

Właściwie uważam, że jest bardzo proste. Sekcja CDATA będzie ładowana do XmlDocument, podobnie jak inna XmlNode różnica polega na tym, że węzeł będzie miał właściwość NodeType = CDATA, co oznacza, że ​​jeśli masz XmlNode node = doc.SelectSingleNode("section/description");, węzeł ten będzie miał ChildNode z właściwością InnerText wypełnioną czystą danych i chcesz usunąć specjalne znaki po prostu użyj Trim(), a otrzymasz dane.

Kod będzie wyglądać

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

Dzięki
XOnDaRocks

8

Myślę, że najlepszym sposobem jest ...

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

string finalData = cDataNode.Data; 
+0

Zdecydowanie najlepsze rozwiązanie, krótkie, bez ciągów Konwersje i wykorzystanie istniejących metod System.Xml. – lgrosales

2

prostszej formie roztworu Franky za:

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

Właściwość Value właściwości is equivalent do odlanego typu odlanego typu XmlCDataSection.