过滤后代父[或至少比结果更高级]

时间:2014-08-18 09:10:58

标签: c# xml linq linq-to-xml

这里仍然是Linq新手,现在遇到了WHERE子句的问题。我正在尝试返回打印机标记中的所有内容,但只能从元素列表 type =“lff”下面找回。

如果我尝试输出没有WHERE子句的后代元素,我会得到所有内容(来自<list>个元素)。当我尝试添加各种版本的WHERE子句时,我什么也得不到。我显然没有正确地放置WHERE条件。

(我需要获取元素对象,所以我可以检查NAME和VALUE。在下面的例子中,我现在只输出VALUE。)

你可以建议吗?

这是XML:

<?xml version="1.0"?>
<printerlist>
  <list type="aff">
    <printserver>print-server1</printserver>
    <printserver>print-server2</printserver>
    <printserver>print-server3</printserver>
    <additionalprinters>
      <printer>
        <fullname>\\servera\bbb</fullname>
      </printer>
    </additionalprinters>
  </list>
  <list type="lff">
    <printserver>print-sever4</printserver>
    <additionalprinters>
      <printer>
        <fullname>\\serverb\bbb</fullname>
      </printer>
      <printer>
        <fullname>\\serverc\aaa</fullname>
      </printer>
    </additionalprinters>
  </list>
</printerlist>

以下是尝试获取列表的代码:

var qq = from c in xml.Descendants("additionalprinters").Descendants("printer")
//where (string) c.Parent.Attribute("type") == "lff"
//Uncommenting the above line means that nothing is returned.
select c;
foreach (XElement q in qq)
{
    Console.WriteLine("Test Output: {0}", q.Value );
}

输出是:

Test Output: \\servera\bbb
Test Output: \\serverb\bbb
Test Output: \\serverc\aaa

在这种特殊情况下,我只是要查找要返回的最后两个输出。

2 个答案:

答案 0 :(得分:2)

printer的父级additionalprinters且没有type属性,您需要使用.Parent两次才能获得list元素。< / p>

from c in xml.Descendants("additionalprinters").Descendants("printer")
where (string) c.Parent.Parent.Attribute("type") == "lff"
select c

或者您也可以执行以下操作

xml.Descendants("list")
.Where(c => (string) c.Attribute("type") == "lff")
.SelectMany(x => x.Element("additionalprinters").Descendants("printer"))

答案 1 :(得分:0)

您还可以使用System.Xml.XPath命名空间中的XPath选择器来实现此目的:

    var doc = XDocument.Parse(xml);
    var printers = doc.XPathSelectElements("//list[@type='lff']/additionalprinters/printer");