14

次のような構造 (部分的に) を持つ既存の XML ドキュメントを使用しています。

<Group>
    <Entry>
        <Name> Bob </Name>
        <ID> 1 </ID>
    </Entry>
    <Entry>
        <Name> Larry </Name>
    </Entry>
</Group>

次のように、LINQ to XML を使用して XDocument をクエリし、これらすべてのエントリを取得しています。

var items = from g in xDocument.Root.Descendants("Group").Elements("Entry")
    select new
    {
        name = (string)g.element("Name").Value,
        id = g.Elements("ID").Count() > 0 ? (string)g.Element("ID").Value : "none"
    };

「ID」要素は常にそこにあるとは限らないため、これに対する私の解決策は上記の Count() ジャズでした。しかし、誰かがこれを行うためのより良い方法を持っているかどうか疑問に思っています。私はまだこの新しいものに慣れてきており、現在行っている方法よりも良い方法があるのではないかと考えています。

私が望むことを行うためのより良い/より好ましい方法はありますか?

4

3 に答える 3

23

XElementには、実際に、この場合に正しいことを行う興味深い明示的な変換演算子があります。

.Valueそのため、実際にプロパティにアクセスする必要はほとんどありません。

プロジェクションに必要なのはこれだけです。

var items =
    from g in xDocument.Root.Descendants("Group").Elements("Entry")
    select new
    {
        name = (string) g.Element("Name"),
        id = (string) g.Element("ID") ?? "none",
    };

IDの値を匿名型の整数として使用したい場合は、次のようにします。

var items =
    from g in xDocument.Root.Descendants("Group").Elements("Entry")
    select new
    {
        name = (string) g.Element("Name"),
        id = (int?) g.Element("ID"),
    };
于 2008-11-10T16:32:20.470 に答える
3

同様の状況で、拡張メソッドを使用しました。

    public static string OptionalElement(this XElement actionElement, string elementName)
    {
        var element = actionElement.Element(elementName);
        return (element != null) ? element.Value : null;
    }

利用方法:

    id = g.OptionalElement("ID") ?? "none"
于 2008-11-10T15:55:19.187 に答える
1

どうですか:

var items = from g in xDocument.Root.Descendants("Group").Elements("Entry")
            let idEl = g.Element("ID")
            select new
            {
                name = (string)g.element("Name").Value,
                id = idEl == null ? "none" : idEl.Value;
            };

この barfs の場合はFirstOrDefault()、その他が役立つ可能性があります。それ以外の場合は、拡張メソッドを使用してください (既に提案されているように)。

于 2008-11-10T15:57:34.517 に答える