web-dev-qa-db-ja.com

すべての子ノードの値ではなく、XElementの値を取得するにはどうすればよいですか?

サンプルxml:

<parent>
<child>test1</child>
<child>test2</child>
</parent>

親がXElementであるparent.Valueを探すと、「test1test2」が返されます。私が期待しているのは「」です。 (のテキスト/値がないため。

XElementのどのプロパティを探す必要がありますか?

26
NiTiN

_<parent>_要素でテキストデータを検索するときは、 NodeType プロパティが _XmlNodeType.Text_ に等しい子ノードを検索する必要があります。これらのノードのタイプは 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);
}
_

更新:必要なのが最初のテキストノードだけである場合、クエリ理解構文の代わりにLINQメソッド呼び出しを使用する例を次に示します。

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

注:First()またはFirstOrDefault()を使用すると、Count() > 0よりもパフォーマンスが向上します。シナリオ。 Countは常にコレクション全体を列挙しますが、FirstOrDefault()は一致するものが見つかるまでのみ列挙します。

25
Peter Lillevold

XText内のすべてのparentノードの値を連結できます。

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)  ==  ""
8
dtb

Microsoftのどこかのコーダーが、すべてのテキスト値を連結された区切りのない文字列として返すことが役立つと考えたのは驚くべきことです。幸いなことに、別のMS開発者がXElement拡張機能を作成して、テキストノードの「浅い値」と呼ばれるものを返しました ここ 。リンクをクリックして意欲を得る人のために、機能は以下の通りです...

    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();
3
Steve Hibbert
// 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
Mehrdad Mirreza

msdn 言います:

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

したがって、動作は予想されます。

次の方法で問題を解決できます。

string textContent = parent.HasElements ? "" : parent.Value;
1
Femaref