2010-11-07 94 views
1

让我们假设一个名为data.xml中有以下内容的XML文件:C#中的LINQ to XML查询帮助

<root> 
<record> 
<id>1</id> 
<name>test 1</name> 
<resume>this is the resume</resume> 
<specs>these are the specs</specs> 
</record> 
<record> 
<id>2</id> 
<name>test 2</name> 
<resume>this is the resume 2</resume> 
</record> 
<record> 
<id>3</id> 
<name>test 3</name> 
<specs>these are the specs 3</specs> 
</record> 
</root> 

我需要搜索的所有记录,其中任何一个字段(ID,姓名,恢复或规格)的含有一个给定的值。我已创建此代码

XDocument DOC = XDocument.Load("data.xml"); 
IEnumerable<ProductRecord> results = from obj in DOC.Descendants("record") 
    where 
obj.Element("id").Value.Contains(valueToSearch) || 
obj.Element("name").Value.Contains(valueToSearch) || 
obj.Element("resume").Value.Contains(valueToSearch) || 
obj.Element("specs").Value.Contains(valueToSearch) 
    select new ProductRecord { 
ID = obj.Element("id").Value, 
Name = obj.Element("name").Value, 
Resume = obj.Element("resume").Value, 
Specs = obj.Element("specs").Value 
    }; 

此代码会抛出NullReference错误,因为并非所有记录都包含所有字段。 我如何测试当前记录是否有给定的元素,然后再定义要应用的条件?防爆。记录[@ ID = 3]没有简历。

在此先感谢

回答

0

你可以写一个扩展方法是像波纹管:

public static class XMLExtension 
{ 
    public static string GetValue(this XElement input) 
    { 
     if (input != null) 
      return input.Value; 
     return null; 
    } 

    public static bool XMLContains(this string input, string value) 
    { 
     if (string.IsNullOrEmpty(input)) 
      return false; 
     return input.Contains(value); 
    } 
} 

和如下使用它:

IEnumerable<ProductRecord> results = from obj in DOC.Descendants("record") 
               where 
              obj.Element("id").GetValue().XMLContains(valueToSearch) || ... 
+0

非常感谢您! – adaoss 2010-11-07 15:58:49

0

你得到一个NullReferenceException因为你试图访问没有为每个recordspecs存在一些节点的值。在调用.Value之前,您需要检查是否为obj.Element("specs") != null

正如你可以使用XPath替代:

var doc = XDocument.Load("test.xml"); 
var records = doc.XPathSelectElements("//record[contains(id, '2') or contains(name, 'test') or contains(resume, 'res') or contains(specs, 'spe')]"); 
0

首先,我惊讶于它没有崩溃,因为你没有使用命名空间。也许C#4.0绕过了这个?

反正尝试

obj.Descendants("id").Any() ? root.Element("id").Value : null 

即:

select new ProductRecord { 
    ID = obj.Descendants("id").Any() ? root.Element("id").Value : null, 
    Name = obj.Descendants("name").Any() ? root.Element("name").Value : null, 
    Resume = obj.Descendants("resume").Any() ? root.Element("resume").Value : null 
    Specs = obj.Descendants("specs").Any() ? root.Element("specs").Value : null 
}; 
+0

问题不在于select,我绕过这段代码Specs =(string)obj.Element(“Specs”)?? “N/A”。主要问题是在where子句... – adaoss 2010-11-07 14:04:33

+0

尝试使用相同的逻辑? (string)obj.Element(“Specs”)??真正。就好像该对象不存在一样,您希望将其作为该记录的真实选项。 – Kamal 2010-11-07 14:13:49