2013-08-02 137 views
4

如何使用C#以正确的方式获取属性“action”和“filename”值?C#从xml属性获取值

XML:

<?xml version="1.0" encoding="utf-8" ?> 
<Config version="1.0.1.1" > 
    <Items> 
    <Item action="Create" filename="newtest.xml"/> 
    <Item action="Update" filename="oldtest.xml"/> 
    </Items> 
</Config> 

C#:我不能得到属性值,以及如何在foreach循环中获取值?如何解决这个问题?

 var doc = new XmlDocument(); 
     doc.Load(@newFile); 
     var element = ((XmlElement)doc.GetElementsByTagName("Config/Items/Item")[0]); //null 
     var xmlActions = element.GetAttribute("action"); //cannot get values 
     var xmlFileNames= element.GetAttribute("filename"); //cannot get values 

     foreach (action in xmlActions) 
     { 
      //not working 
     } 

     foreach (file in xmlFileNames) 
     { 
      //not working 
     } 

你的代码示例对我意味着很多。谢谢!

+1

您可能想查看[LINQ to XML](http://msdn.microsoft.com/library/bb387087.aspx)。它使得使用XML更容易。 – Corak

回答

7

您可以使用LINQ to XML。下面的查询返回强类型项目的收集与ActionFileName属性:

var xdoc = XDocument.Load(@newFile); 

var items = from i in xdoc.Descendants("Item") 
      select new { 
       Action = (string)i.Attribute("action"), 
       FileName = (string)i.Attribute("fileName") 
      }; 

foreach (var item in items) 
{ 
    // use item.Action or item.FileName 
} 
+0

var items = for i in xdoc (“Item”) 选择新动作=(string)i.Attribute(“action”), FileName =(string)i.Attribute(“fileName”) };不正确的代码语法 – user235973457

+0

@ user235973457对不起,错字。它应该是'from'而不是'' –

+1

它的工作,非常感谢! – user235973457

3

GetElementsByTagName会发现你只有直系后代。该参数应该是只是标签名称,而不是整个元素的路径。

如果要在提供XPath表达式的同时在文档中进行搜索,请改为使用SelectNodes

对于您的文档,它应该是这样的:

var element = (XmlElement)doc.SelectNodes("/Config/Items/Item")[0]; 
+0

我已经尝试过SelectNode,但不知道如何在代码中使用它。你能给我举例代码吗? – user235973457

+0

@ user235973457:我已添加示例性呼叫;我现在不能尝试,但我希望命名空间不会有问题。如果您遇到任何错误,请包括确切的错误消息,我或此处的任何其他人将在稍后尝试。 –

+0

好的谢谢,我希望任何人都能帮助解决这个问题。 :) – user235973457

2

你可以实现你与LINQ to XML问什么:

// For each element that is a child of your Items element that is named Item 
foreach (var item in XElement.Load("file.xml").Descendants("Items").Elements("Item")) 
{ 
    // If the element does not have any attributes 
    if (!item.Attributes().Any()) 
    { 
     // Lets skip it 
     continue; 
    } 

    // Obtain the value of your action attribute - Possible null reference exception here that should be handled 
    var action = item.Attribute("action").Value; 
    // Obtain the value of your filename attribute - Possible null reference exception here that should be handled 
    var filename = item.Attribute("filename").Value; 

    // Do something with your data 
    Console.WriteLine("action: {0}, filename {1}", action, filename); 
} 
2

有与问题的代码一堆问题:
1.您正在使用的的getElementsByTagName的XPath,只需使用标签
2.您只通过使用[0]
获取XmlNodeCollection中的第一个XmlNode 3.由于您只有一个XmlNode,因此只会获取用于获取属性的字符串结果,而不是字符串集合,你然后试图通过
枚举4.你的foreach是坏了,没有类型生成的对象

这里是将工作的一个片段:

var doc = new XmlDocument(); 
doc.Load("test.xml"); 
var items = doc.GetElementsByTagName("Item"); 

var xmlActions = new string[items.Count]; 
var xmlFileNames = new string[items.Count]; 
for (int i = 0; i < items.Count; i++) { 
    var xmlAttributeCollection = items[i].Attributes; 
    if (xmlAttributeCollection != null) { 
     var action = xmlAttributeCollection["action"]; 
     xmlActions[i] = action.Value; 

     var fileName = xmlAttributeCollection["filename"]; 
     xmlFileNames[i] = fileName.Value; 
    } 
} 

foreach (var action in xmlActions) { 
    //working 
} 

foreach (var file in xmlFileNames) { 
    //working 
} 

或者,如果你采取行动之前并不需要一个集合中的所有行动和文件名他们,你可以对for循环中的每个动作/文件名采取行动。