2012-08-16 100 views
0

美好的一天,C#查询XML文档

我想查询一个XML文档,有以下查询:

XElement root = XElement.Load(@"..\..\Data.xml"); 
var entries = root.Descendants() 
       .Where(x => x.Name.LocalName == "Entry") 
       .ToList(); 

Console.WriteLine("There are {0} nodes...", entries.Count()); 
foreach (XElement v in entries) 
{ 
    Console.WriteLine(v.Value); 
} 

与此代码的工作,因为它拉入口节点的正确数目。该条目 节点样子:

<?xml version="1.0" encoding="UTF-8"?> 
<Database xmlns="http://www.someurl.org/schemas"> 
    <InfoFromRecord> 
     <BaseData> 
      <Entry> 
       <Date>2006-03-08</Date>XD 
       <Time>09:20:00</Time> 
       <EnteredBy>DNS</EnteredBy> 
       <TextEntry>Record 1</TextEntry> 
      </Entry> 
      <Entry> 
       <Date>2006-03-08</Date> 
       <Time>09:33:00</Time> 
       <EnteredBy>MW</EnteredBy> 
       <TextEntry>Record 2</TextEntry> 
      </Entry> 
      <Entry> 
       <Date>2006-03-08</Date> 
       <Time>08:58:00</Time> 
       <EnteredBy>BH</EnteredBy> 
       <TextEntry>Record 3</TextEntry> 
      </Entry> 
     </BaseData> 
    </InfoFromRecord> 
</Database> 

的问题是,我想只提取日期和时间,不是所有的四个字段。

回答

3

让我们假设你的整个XML文件是这样一个明显的例子:

<Entries> 
    <Entry> 
     <Date>2006-03-08</Date> 
     <Time>09:33:00</Time> 
     <EnteredBy>XX</EnteredBy> 
     <TextEntry>Test Data</TextEntry> 
    </Entry> 
</Entries> 

然后,您可以做这样的事情:

var document = XDocument.Load(@"..\..\Data.xml"); 
var dateAndTimes = 
    from d in document.Root.Descendants("Entry") 
    select new 
       { 
        Date = d.Element("Date").Value, 
        Time = d.Element("Time").Value 
       }; 

从那里,dateAndTimes类型将选择日期和时间的anonymous type。您可以将匿名类型更改为您自己的类型或其他类型。


编辑:问题是你xmlns。改变你的代码是这样的:

XNamespace namespc = "http://www.someurl.org/schemas"; 
var document = XDocument.Parse(xml); 
var dateAndTimes = 
    from d in document.Root.Descendants(namespc + "Entry") 
    select new 
       { 
        Date = d.Element(namespc + "Date").Value, 
        Time = d.Element(namespc + "Time").Value 
       }; 
+0

我试过了,它没有工作。它看起来像document.Root.Descendants(“Entry”)中没有任何内容。我认为后裔会得到文件中的任何节点。 – coson 2012-08-16 16:08:16

+0

@coson编辑与更新回答。命名空间没有被考虑在内。 – vcsjones 2012-08-16 16:14:06

+0

工作。原来,没有前缀的默认名称空间需要考虑。 – coson 2012-08-16 16:17:41

0
foreach (XElement v in entries) 
{ 
    Console.WriteLine(v.Element("Date").Value); 
    Console.WriteLine(v.Element("Time").Value); 
} 

不要忘记Descendants在任何级别,即儿童,盛大的孩子,等孩子发现其中Elements只找到直接的孩子。所以我想Elements是大多数情况下的安全选择。

编辑:看到XML

后,您需要包括Namspace也获得数据

XNamespace ns = "http://www.someurl.org/schemas"; 
var entries = elm.Descendants().Where(x => x.Name.LocalName == "Entry").ToList(); 
foreach (XElement v in entries) 
{ 
    Console.WriteLine(v.Element(ns+"Date").Value); 
    Console.WriteLine(v.Element(ns+"Time").Value); 
} 
+0

对不起,我试过这个,它不工作。我得到一个空引用异常 – coson 2012-08-16 15:53:37

+0

你可以发布你的xML吗? – Shyju 2012-08-16 15:56:21

+0

我现在把整个文档放在那里。 – coson 2012-08-16 16:08:57

0

的时候我还没有机会尝试,但像下面可能给你你在找什么

var entries = from i in root.Descendants() 
where Name=='entry' 
let date = i.Element('Date').Value 
let time = i.ELement('Time').Value 
select new Tuple<string,string>(date,time);