如何使用Linq执行此XPath查询?

时间:2010-06-15 19:26:44

标签: c# linq-to-xml

在下面的代码中,我使用XPath使用XPath查找所有匹配的节点,并将值附加到StringBuilder。

StringBuilder sb = new StringBuilder();
foreach (XmlNode node in this.Data.SelectNodes("ID/item[@id=200]/DAT[1]/line[position()>1]/data[1]/text()"))
{
    sb.Append(node.Value);
}
return sb.ToString();

除了使用Linq to XML之外,我该如何做同样的事情?假设在新版本中,this.Data是一个XElement对象。

4 个答案:

答案 0 :(得分:1)

您仍然可以将XPath与XElement一起使用。您必须包含System.Xml.XPath命名空间,因为它是一个扩展方法

var xml = XDocument.Parse("<xml></xml>");
var elements = xml.XPathSelectElements("ID/item[@id=200]/DAT[1]/line[position()>1]/data[1]/text()");

答案 1 :(得分:0)

查询语法看起来像这样。

var nodes = from item in Data.Elements("item")
            where item.Attribute("id").Value == "200"
            let dat = item.Element("DAT")
            from line in dat.Elements("line").Skip(1)
            let data = line.Element("data")
            select data;

var sb = new StringBuilder();
foreach (var node in nodes)
    sb.Append(node.Value);

...这将摆脱可能的nullref异常,并将摆脱foreach循环。

var nodes = from item in Data.Elements("item")
            let id = item.Attribute("id")
            where id != null && id.Value == "200"
            let dat = item.Element("DAT")
            where dat != null
            from line in dat.Elements("line").Skip(1)
            let data = line.Element("data")
            where data != null
            select data.Value;
return nodes.Aggregate(new StringBuilder(), (sb, r) => sb.Append(r))
            .ToString();

答案 2 :(得分:0)

你可以尝试这样的事情:

var query = 
    from id in this.Data.Elements("ID")                      // ID
    from item in id.Elements("item")                         // /item
    where item.Attribute("id").Value == "200"                // [@id=200]
    let dat in item.Elements("DAT").ElementAtOrDefault(1)    // /DAT[1]
    where dat != null                                        // (ensure there is an element at index 1)
    from line in dat.Elements("line").Skip(1)                // /line[position()>1]
    let data in line.Elements("data").ElementAtOrDefault(1)  // /data[1]
    where data != null                                       // (ensure there is an element at index 1)
    select data                                              // /text()

StringBuilder sb = new StringBuilder();
foreach(XElement data in query)
{
    sb.Append(data.Value);
}
return sb.ToString();

正如您所看到的,它并不比XPath更方便,所以您应该继续使用XPath(如Pierre-Alain的回答中所述)

答案 3 :(得分:0)

我创建了一个开源帮助程序库,让您使用Linq-esq表达式生成xpath表达式。不确定它在您的上下文中是否有用,但是将链接发布到API

http://www.syntaxsuccess.com/viewarticle/how-to-create-xpath-using-linq