XDocument:获取 'a' 或 'b' 类型的第一个子元素

XDocument: get the first child element of type 'a' or 'b'

我有以下标记,其中每个 item 元素 必须 恰好包含一个 abcd 元素,此外还可以包含各种附加元素。所需的(ab...类型)元素的位置不确定。

<root>
  <item>
    <a>...</a>
    ...
  <item>

  <item>
    ...
    <d>...</d>
  <item>

  <item>
    <c>...</c>
  <item>

  ...
</root>

使用XDocument,我如何表达以下内容:

Return the first child element of type a, b, c, or d.

我目前正在使用一系列 if-else 语句,但这种亵渎行为必须取消;对于这样一个看似简单的任务来说似乎太过分了:

foreach (XElement xItem in xmlDoc.Root.Elements("item"))
{
    if (xItem.Element("a") != null)
    {
        // element <a>...</a> found
    }
    else if (xItem.Element("b") != null)
    {
        // element <b>...</b> found
    }
    ...
}

您可以使用 FirstOrDefault 完成此任务:

var firstAorBorCorD = xmlDoc.Root
    .Elements("item")
    .Select(xItem =>
        xItem.Elements().FirstOrDefault(sub =>
            sub.Name == "a" || sub.Name == "b" || sub.Name == "c" || sub.Name == "d"
        )
    );

这将为每个 item 生成一个类型为 {a, b, c, d} 的第一个子序列。如果特定项目没有所需类型的子项,则其在列表中的对应条目将为 null.

听起来你可能想要这样的东西:

var names = new XName[] { "a", "b", "c", "d" };
var element = xmlDoc.Root
                    .Elements("item")
                    .Elements()
                    .FirstOrDefault(x => names.Contains(x.Name));

据我了解,您仍然希望保留 for 循环,因为您希望相对于其包含的元素做一些事情 Item,但您希望代码先获取 abcd 元素清洁器。

以下是您的操作方法:

var names = new XName[] { "a", "b", "c", "d" };

foreach (XElement xItem in xmlDoc.Root.Elements("item"))
{
    var element = xItem.Elements().FirstOrDefault(x => names.Contains(x.Name));
    //Do something with element
}