8

LINQ to XMLの使用を開始したばかりで、すべての子要素のテキスト コンテンツも取得せずに、特定の XElement のテキスト コンテンツを取得するのに問題があります。

たとえば、次の XML ドキュメントがあるとします。

<?xml version="1.0" encoding="utf-8" ?>
<root xmlns="example.org/rootns">This is root value
    <children>
        <child name='child 1'>value 1</child>
        <child name='child 2'>value 2
            <grandchild name='grandchild A'>value A</grandchild>
        </child>
    </children>
</root>

そして、次の Test メソッドを使用します。

private static void Test()
{
    string xString = @"<?xml version=""1.0"" encoding=""utf-8"" ?><root xmlns=""example.org/rootns"">This is root value<children><child name='child 1'>value 1</child><child name='child 2'>value 2<grandchild name='grandchild A'>value A</grandchild></child></children></root>";

    var xDoc = XDocument.Parse(xString);

    XNamespace ns = @"example.org/rootns";
    string elemName = "child";

    var xElems = from e in xDoc.Descendants(ns + elemName)
                 select e;

    foreach (var xElem in xElems)
    {
        Console.WriteLine(xElem.Value);
    }
}

次に、出力に次の 2 行が表示されます。

    value 1
    value 2value A

最初の行は最初の子の内容を示しています - これで問題ありません。ただし、2 行目には、最初の子のテキスト コンテンツだけでなく、その子の子孫も表示されます。

孫のテキスト コンテンツなしで 2 番目の子だけのテキスト コンテンツを取得するにはどうすればよいですか?

また、サンプルは私が何をしているかを説明するための単純な例にすぎないことに注意してください。実稼働環境では、子要素が何と呼ばれているか (存在する場合) は必ずしもわかりませんが、取得する必要がある要素を取得できるはずです。からのテキストコンテンツ。


Jon Skeet の回答が解決に役立ちました。foreach ループを次のように置き換えるだけで、XElement の値ではなくテキスト XNode を選択できます。

...
foreach (var xElem in xElems)
{
    var values = from n in xElem.Nodes()
                 where n.NodeType == System.Xml.XmlNodeType.Text
                 select n;

    if (values != null && values.Count() > 0)
        Console.WriteLine(values.First());
}
4

1 に答える 1

8

複数のテキスト ノードがある場合はどうしますか? たとえば、それらをすべて結合できます。

var text = string.Join("", element.Nodes.OfType<XText>().Select(x => x.Value));

編集:単一の要素のみが必要な場合は、示したよりも簡単です:

var textNode = xElem.Nodes().OfType<XText>().FirstOrDefault();
if (textNode != null)
{
    Console.WriteLine(textNode.Value);
}
于 2012-04-24T16:45:40.217 に答える