2009-07-23 23 views
6

私はC#を初めて使い、XmlElementとそのSelectSingleNodeメソッドを使い始めました。私のXMLファイルには、値(つまり<tag>value</tag>)を持つか、空白(つまり<tag></tag>)のタグがあります。空の場合、SelectSingleNodeはnullを返します。C#XmlElement:SelectSingleNodeは空の文字列に対してnullを返しますか?

私は現在、タグの値をキャッチするために、次のコードを使用しています:

XmlElement elem = .... 
string s = elem.SelectSingleNode("somepath").Value; 

このコードは明らかに空のタグの例外を発生させます。しかし、私にとって空のタグは有効な値で、私は文字列の値が ""と期待しています。

try ... catchを使用してSelectSingleNodeを呼び出すたびにコードが大量になります(空のフィールドが多数あります)。これを実現するにはより良い方法があると確信しています。

推奨されるアプローチは何ですか?

EDIT:

要求に続いて、サンプルXMLコードは次のようになります。

<Elements> 
    <Element> 
     <Name>Value</Name> 
     <Type>Value</Type> <-- may be empty 
     <Color>Value</Color> 
    </Element> 
    <Element> 
     <Name>Value</Name> 
     <Type>Value</Type> 
     <Color>Value</Color> 
    </Element> 
</Elements> 

CSコード:

XmlDocument doc = new XmlDocument(); 
doc.Load("name.xml"); 

foreach (XmlElement elem in doc.SelectNodes("Elements/Element")) 
{ 
    myvalue = elem.SelectSingleNode("Type/text()").Value; 
} 
+3

さらに完全なコードサンプルを投稿できますか?または、提供されたXMLブロックと直接相関関係があるものはありますか? –

+0

サンプルXMLを投稿できますか? –

+0

はい、もう少しコードサンプルとそれを解析するために使用しているXMLです。私は過去にSelectSingleNodeを使用しており、あなたが言及した動作を見ていません。 – SolutionYogi

答えて

10

あなたのサンプルコード:問題がどこにある

myvalue = elem.SelectSingleNode("Type/text()").Value; 

です。あなたがそこで使ったXPath式は、「私に要素のテキストを与えよう」という意味ではありません。Typeこれは、「要素タイプのすべての子テキストノードを私に渡す」という意味です。また、空の要素には子テキストノードがありません(XPathドキュメントモデルではテキストノードを空にすることはできません)。ノードのテキスト値を取得する場合は、次のようにします。

myvalue = elem.SelectSingleNode("Type").InnerText; 
+0

これは問題でした。ありがとうございました –

+0

InnerTextは、「ノードとそのすべての子ノードの連結値」を提供することに注意してください。あなたは子供がいるときに期待するテキストを取得しません。私は(foundNode.NodeType == XmlNodeType.Element){foundNode = foundNode.SelectSingleNode( "text()");をチェックするヘルパーを実装しました。見つかった場合はfoundNode == null {return ""; }}戻り値foundNode.Value; –

1

推奨されるアプローチは、.NETの新しいXML APIを使用することです(つまり、LINQ to XML)。ここで

は一例です:

using System; 
using System.Linq; 
using System.Xml.Linq; 

class Program 
{ 
    static void Main() 
    { 
     String xml = @"<Root><Value></Value></Root>"; 

     var elements = XDocument.Parse(xml) 
      .Descendants("Value") 
      .Select(e => e.Value); 
    } 
} 
+0

LINQ to XMLは「新しいXML API」ではありません。確かに、既存のSystem.Xml名前空間を使用する理由があります。 LINQは、その名前空間内のクラスを使用する単純な手段です。 –

+0

私は同意しません - System.Xml.Linqには、XMLを扱うための新しい型の配列が含まれています。これは本当にXMLを扱うための新しいAPIです。 –

0

多分これはあなたのために動作します:

string s = elem.SelectSingleNode("somepath") != null ? elem.SelectSingleNode("somepath").value : "" 
+0

これはうまくいくが、SelectSingleNodeは2回実行されるため、不必要なパフォーマンスが発生する。 – Thorarin

+1

それでは、SelectSingleNode( "// blah")というXMLの欠落要素を処理する方法は何ですか?innertextは例外をスローしますか?無限の第三演算子ではないと教えてください... – Fireworks

1

http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.value(VS.71).aspx

返された "値" は、ノードタイプによって異なりますので、チャンスがありますノードがNULLを返すことができる型として解釈されることを意味します。

あなたが使用したほうが良いかもしれません:XMLNode.InnerText(またはXmlNode.InnerXML)など

XmlElement elem = .... 
string s = elem.SelectSingleNode("somepath").InnerText; 

は空の文字列を含む、文字列を返します。あなたのノードが存在しますわからない場合、あなたは次の操作を行うことができます

static string NodeValue(XmlNode node, string defaultValue) 
{ 
    if (node != null) 
     return node.Value ?? defaultValue; 

    return defaultValue; 
} 

::私は実際にXML DOMを悩ませていた場合

+1

これは動作しません。SelectSingleNodeがnullを返した場合、InnerTextを呼び出すことはありません。 – Thorarin

+0

@Thorarn:正しい。質問(および例)は、タグがテキストの間に存在するだけでノードが存在することを示しています。値を確認する前にNullノードをチェックすることを強くお勧めします。 –

+0

あなたはノードの存在について正しいです...彼の説明はSelectSingleNodeがnullを返すことに関して何か言及しましたが、そこに要素がある場合は空ではありません – Thorarin

0

、あなたの線に沿ってヘルパーメソッドを書くことができ

string s = NodeValue(elem.SelectSingleNode("Type"), String.Empty); 

Ifは、特に複数の要素に対してこれを実行している場合は、コードを読み取り可能にします。

SelectSingleNode(..)は、ではありません。は、タグが空の場合はnull値を返します。 の属性はnullになります。あなたはちょうどそれを回避しようとしている場合、これは実行する必要があります。

string s = elem.SelectSingleNode("Type").Value ?? String.Empty; 

編集:ああ、あなたが使用している/テキストを()実際のテキストノードを選択します。あなたはXPathのその部分を取り除くことができますが、私が提供したNodeValueメソッドはまだ動作するはずです( "?? defaultValue"の部分は必要ありません)。

+0

これはうまく動作します。ノード自体が!= Nullであることを確認しますが、ノードは存在し、NodeTypeが何であるかに基づいてNULLとしてnode.Valueを返します。 –

+0

@Paige:確かに可能です。 XMLについてその前提を立てられない場合は、より多くのチェックを行う必要があります。または、事前にXSDに対して検証してください。私はnullを返さないようにメソッドを少し更新しました。 – Thorarin

関連する問題