2010-11-22 31 views

答えて

24

テキストデータを探して<parent>要素では、NodeTypeプロパティがに等しい子ノードを検索する必要があります210。これらのノードのタイプはXTextです。次のサンプルでは、​​この説明:

var p = XElement 
    .Parse("<parent>Hello<child>test1</child>World<child>test2</child>!</parent>"); 

var textNodes = from c in p.Nodes() 
       where c.NodeType == XmlNodeType.Text 
       select (XText)c; 

foreach (var t in textNodes) 
{ 
    Console.WriteLine(t.Value); 
} 

更新:

var firstTextNode = p.Nodes().OfType<XText>().FirstOrDefault(); 
if (firstTextNode != null) 
{ 
    var textValue = firstTextNode.Value; 
    ...do something interesting with the value 
} 

:あなたが望むすべてが最初のテキスト・ノードである場合は、もしあれば、ここでは代わりにクエリの理解の構文の呼び出し、LINQメソッドを使用した例です注:First()またはFirstOrDefault()を使用すると、このシナリオではCount() > 0よりパフォーマンスが向上します。 Countは常にコレクション全体を列挙し、一方FirstOrDefault()は一致するものが見つかるまで列挙します。

+0

CDataセクションはどうですか? (XmlNodeType.CDATA) – dtb

+0

@dtb - cdataセクションが 'XCData'ノードとして見つかります。 TextとCDataの両方を返すようにクエリを簡単に拡張することができます。 –

+0

私は問題をかなりあなたの方法で解決しました...しかし、あなたの答えはよりエレガントに見えます。私のコード:if(parent.Nodes()!= null && parent.Nodes()。OfType ().Count()> 0) parentValue = parent.Nodes()OfType ().First()。Value ; – NiTiN

1

msdnを探してしなければならないのXElementのどのような性質

には、テキスト/値が存在しないので、(と言う:

この要素のテキストコンテンツのすべてを含むString。複数のテキストノードが存在する場合、それらは連結されます。

ので、動作が予想される。

あなたが行うことで、あなたの問題を解決することができます:

string textContent = parent.HasElements ? "" : parent.Value; 
+3

混在コンテンツ要素はどうですか?例えば'こんにちは test1世界 test2 ' – dtb

+0

@dtb:parentには、2つの子の子と2つのTextNodeの子が含まれます。 –

+0

私の心はバグがあると考えてください。私はこれがxmlで許可されたことを知らなかった。 – Femaref

6

をあなたはparent内のすべてのXTextのノードの値を連結できます。比較のために

XElement parent = XElement.Parse(
    @"<parent>Hello<child>test1</child>World<child>test2</child>!</parent>"); 

string result = string.Concat(
    parent.Nodes().OfType<XText>().Select(t => t.Value)); 

// result == "HelloWorld!" 

を:

// parent.Value == "Hellotest1Worldtest2!" 

// (parent.HasElements ? "" : parent.Value) == "" 
+0

'Concat'は、リスト内の文字列を連結しないので、期待通りの結果を得ることはできませんが、そのパラメータの_type name_、ここでは文字列の' IEnumerable'を返します。 'string.Join(" "、element.Nodes()。OfType ().Select(t => t.Value).ToArray()); – Evariste

0
// Create the XElement 
XElement parent = XElement.Parse(
    @"<parent>Hello<child>test1</child>World<child>test2</child>!</parent>"); 

// Make a copy 
XElement temp=new XElement(parent); 

// remove all elements but root 
temp.RemoveNodes(); 

// now, do something with temp.value, e.g. 
Console.WriteLine(temp.value); 
1

どこかにMicrosoftのコーダは、連結および区切り文字のない文字列としてすべてのテキスト値を返すことは有用であろうと思ったのは驚くべきことです。幸いにも、別のMS開発者はXElement拡張を書いて、テキストノードhereの "Shallow Value"と呼ばれるものを返すようになりました。あなたは、リンクをクリックから・ウィリーズを取得する人のために、機能は以下の通りです...

public static string ShallowValue(this XElement element) 
    { 
     return element 
       .Nodes() 
       .OfType<XText>() 
       .Aggregate(new StringBuilder(), 
          (s, c) => s.Append(c), 
          s => s.ToString()); 
    } 

そして、それは考えてみると、あまりにもあなたのすべての空白を与える(またはので、あなたは、このようにそれを呼び出しますどのようなものでも拡張子でトリムできます)

// element is a var in your code of type XElement ... 
string myTextContent = element.ShallowValue().Trim(); 
関連する問題