web-dev-qa-db-ja.com

C#でCDATAセクションをデコードします

私は次のようにXMLを少し持っています:

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

curXmlNode.SelectSingleNode("description").InnerTextを使用してアクセスしていますが、値は

\ r\nこれは私がフォーマットした「説明」です\ r\n
これは私がフォーマットした「説明」です。

CDATAセクションからそのような出力を取得する簡単な方法はありますか?実際のCDATAタグを除外すると、同じように返されるようです。

11
Jess

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の場合、おそらく正規表現を通過する必要があります。

     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つ以上の空白を1つのスペースに置き換えます。 CDATAがかなりの空白を返していることを考えると、他に方法はないと思います。

17
Jim Schubert

最善の方法は...

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

string finalData = cDataNode.Data;
9
Franky

実際、私はかなり簡単だと思います。 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

9
XOnDaRocks

より単純な形式 @ Frankyのソリューション

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

Valueプロパティ 同等 キャストされたDataタイプのXmlCDataSectionプロパティと同じです。

4
Arithmomaniac

CDATAブロックは事実上逐語的です。 XML仕様によれば、CDATA内の空白は、定義上、重要です。したがって、ノード値を取得すると、その空白が取得されます。独自のルールを使用して削除する場合(XML仕様ではCDATAの空白を削除する標準的な方法が指定されていないため)、必要に応じてString.ReplaceRegex.Replaceなどを使用して自分で削除する必要があります。 。

3
Pavel Minaev