如何解析XML文件,以获得特定的数据有效

问题描述:

我有一个XML文件是这样的:如何解析XML文件,以获得特定的数据有效

<?xml version="1.0" encoding="utf-8" ?> 
<PathMasks> 
<Mask desc="Masks_X1"> 
    <config id="01" mask="88" /> 
    <config id="03" mask="80" /> 
    <config id="51" mask="85" /> 
    </Mask> 

<Mask desc="Masks_X2"> 
    <config id="70" mask="1" /> 
    <config id="73" mask="6" /> 
    </Mask> 

<Types> 
    <path id="01" desc="TC->PP1" /> 
    <path id="02" desc="TC->PP2" /> 
    <path id="03" desc="TC->PPn" /> 
    </Types> 
    </PathMasks> 

如何解析文件,并得到Mask_X1的所有数据如下:

id value 
===== 
01, 88 
03, 80 
51, 85 
我使用

了.NET Framework 2.0

使用XmlDocument(较慢,占用更大的内存,读/写,作品以同样的方式XML DOM的工作无处不在):

XmlDocument d = new XmlDocument(); 
d.Load(filename); 
string xpath = "/PathMasks/Mask[@desc='Mask_X1']/config" 
foreach (XmlElement elm in d.SelectNodes(xpath)) 
{ 
    Console.WriteLine(elm.GetAttribute("id"), elm.GetAttribute("desc")); 
} 

使用XPathDocument(更快,更小的内存占用,只读,奇怪的API):

XPathDocument d = new XPathDocument(filename); 
string xpath = "/PathMasks/Mask[@desc='Mask_X1']/config" 
XPathNodeIterator iter = d.CreateNavigator().Select(xpath); 
while (iter.MoveNext()) 
{ 
    Console.WriteLine(iter.Current.GetAttribute("id"), iter.Current.GetAttribute("desc')); 
} 

我敢肯定有一个非常好的理由不存在的XPathNavigator方法返回一个IEnumerable<XPathNavigator>,以便可以像遍历正常人一样遍历XPath查询的结果,但我一直无法解决这个问题。

+0

'XPathDocument'早于'IEnumerable '。随意编写自己的扩展方法来执行此操作,然后在此处发布。 – 2010-03-09 15:53:03

+0

其中一天,我会记住技术是按照它们被引入的顺序引入的,而不是按照我了解它们存在的顺序引入的。 – 2010-03-09 16:41:44

使用的XDocument和查询到它的LINQ to XML

XDocument doc = XDocument.Load("file.xml"); 
var linqtoxml = from node in document.Descendants("Mask") 
    where (string)node.Attribute("desc").Value == "Masks_X1" 
    select node; 
foreach (var mask in linqtoxml) 
{ 
    // pull data out of here into a structure of your choosing 
} 
+0

我使用的是.NET 2.0,似乎在System.Xml命名空间中没有linq – 2010-03-09 10:21:30

+1

在这种情况下,你几乎坚持使用XmlDocument和XPath查询。 – ZombieSheep 2010-03-09 10:35:42

使用LINQ to XML:

XDocument doc = XDocument.Load(filename); 
var query = from mask in doc.Root.Elements("Mask") 
      where mask.Attribute("desc").Value == "Masks_X1" 
      from config in mask.Elements("config") 
      select new 
      { 
       id = config.Attribute("id").Value, 
       value = config.Attribute("mask").Value 
      }; 

foreach(var mask in query) 
{ 
    Console.WriteLine("{0}\t{1}", mask.id, mask.value); 
} 

当你正在使用的.Net 2.0的工作,你会不会有LINQ的,因此需要使用XPath,这个样本应该帮助你。

 XmlDocument doc = new XmlDocument(); 

     doc.Load(pathToXmlDoc); 


     XmlNode node = doc.SelectSingleNode("/PathMasks/Mask[@desc='Masks_X1']"); 

     foreach (XmlNode config in node) 
     { 
      Console.WriteLine("{0}\t{1}", 
          config.Attributes["id"].Value, 
          config.Attributes["mask"].Value); 
     } 
+0

'SelectSingleNode'返回单个节点或null。你不能迭代结果。 – 2010-03-09 15:53:46

+0

使用SelectSingleNode确实会返回单个XmlNode。但是,每个XmlNode都包含一组子节点,本示例中的foreach遍历选定的单个Mask节点下的每个子节点。因此,在本例中,SelectSingleNode将选择具有保存值Mask_X1的desc属性的Mask节点。返回的XmlNode的ChildNodes属性将为Mask节点下的每个配置节点保存三个条目。我们可以迭代子节点并生成所需的输出。 – 2010-03-09 21:03:32