当找不到查询节点时,LINQ for XML返回“默认节点”

时间:2016-10-22 23:43:34

标签: c# xml linq

我有这段代码:

string name = "1";
string company = "abc";

XElement config = XElement.Parse (
@"<config>
    <applLists>
        <applList name='1'>
            <default>
                <applName>appl1-default-1</applName>
                <applName>appl2-default-1</applName>
            </default>
            <abc>
                <applName>appl1-abc-1</applName>
                <applName>appl2-abc-1</applName>
            </abc>
        </applList>
        <applList name='2'>
            <default>
                <applName>appl1-default-2</applName>
                <applName>appl2-default-2</applName>
            </default>
            <abc>
                <applName>appl1-abc-2</applName>
                <applName>appl2-abc-2</applName>
            </abc>
        </applList>
    </applLists>
</config>");

var applNames =
    from applList in config.Elements("applLists").Elements("applList")
    from al in applList.Elements()
    where (string)applList.Attribute("name") == name
    where al.Name == company
    select al.Value;

if (!applNames.Any()) {
    applNames =
        from applList in config.Elements("applLists").Elements("applList")
        from al in applList.Elements()
        where (string)applList.Attribute("name") == name
        where al.Name == "default"
        select al.Value;
}

return applNames.ToList<string>();

两个问题:

  1. 问题是结果不是两个值的列表。相反,我得到一个字符串返回“appl1-abc-1appl2-abc-1”。我究竟做错了什么??请帮忙!!
  2. 是否有可能将两个LINQ查询合并为一个?表示如果未找到公司“abc”,则返回“默认”节点的applNames。
  3. 感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

以下是LinqPad program使用方法语法:

void Main()
{
    SoQuestion("1", "abc").Dump();
    SoQuestion("1", "foo").Dump();
    SoQuestion("2", "abc").Dump();
    SoQuestion("2", "bar").Dump();
}

public List<string> SoQuestion(string name, string company)
{
    XElement config = GetXml();

    var applList = config.Elements("applLists")
                         .Elements("applList")
                         .Where(x => x.Attribute("name").Value == name);
    return applList.Elements(company).Any()
         ? applList.Elements(company)
                   .Elements("applName")
                   .Select(x => x.Value).ToList()
         : applList.Elements("default")
                   .Elements("applName")
                   .Select(x => x.Value).ToList();
}

private XElement GetXml()
{
    return XElement.Parse(
    @"<config>
        <applLists>
            <applList name='1'>
                <default>
                    <applName>appl1-default-1</applName>
                    <applName>appl2-default-1</applName>
                </default>
                <abc>
                    <applName>appl1-abc-1</applName>
                    <applName>appl2-abc-1</applName>
                </abc>
            </applList>
            <applList name='2'>
                <default>
                    <applName>appl1-default-2</applName>
                    <applName>appl2-default-2</applName>
                </default>
                <abc>
                    <applName>appl1-abc-2</applName>
                    <applName>appl2-abc-2</applName>
                </abc>
            </applList>
        </applLists>
    </config>");
}

这给出了以下结果:

enter image description here

我暂时没有使用XML,因此可能会有更好的属性或方法调用。

答案 1 :(得分:0)

我假设查询的a部分中的from a in applList.Elements()变量实际上应该是al,否则代码不会编译。通过这种改变,我可以重现你的问题。

您将结果作为连接字符串获取的原因是因为您要求al.Value引用<abc>节点的值。 XElement.Value返回所有子元素的连接文本。你真正想要的是<applName> <abc>个孩子的价值观。因此,您需要修改查询以获取这些信息:

var applNames =
    from applList in config.Elements("applLists").Elements("applList")
    from al in applList.Elements()
    from an in al.Elements()
    where (string)applList.Attribute("name") == name
    where al.Name == company
    select an.Value;

要将两个查询合并为一个,我会像这样重写:

var applNames = config.Elements("applLists").Elements("applList")
    .Where(al => al.Attribute("name").Value == name)
    .Select(al => al.Elements(company).Any() ? al.Elements(company) : al.Elements("default"))
    .SelectMany(e => e.Elements("applName"))
    .Select(an => an.Value)
    .ToList();

小提琴:https://dotnetfiddle.net/ihbRC6