C# 从 xml 属性中获取值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18017692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:03:34  来源:igfitidea点击:

C# get values from xml attributes

c#xmlxmldocument

提问by user235973457

How to get attribute "action" and "filename" values in a right way using C#?

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

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#:i cannot get attribute values as well as how to get values in foreach loops? How to solve this?

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
         }

Your code example means alot to me. Thanks!

您的代码示例对我来说意义重大。谢谢!

采纳答案by Sergey Berezovskiy

You can use LINQ to XML. Following query returns strongly typed collection of items with Actionand FileNameproperties:

您可以使用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
}

回答by O. R. Mapper

GetElementsByTagNamewill find you onlydirect descendants. The argument is supposed to be just a tag name, not a whole path of elements.

GetElementsByTagName会发现你只能直接后裔。参数应该只是一个标签名称,而不是整个元素路径。

If you want to search across the document while supplying an XPath expression, use SelectNodesinstead.

如果要在提供 XPath 表达式的同时搜索整个文档,请SelectNodes改用。

For your document, it should look like this:

对于您的文档,它应该如下所示:

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

回答by O. R. Mapper

You can achieve what you're asking with LINQ to XML:

您可以使用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);
}

回答by Paul Day

There are a bunch of problems with the code in the question:
1. You are using an XPath in the GetElementsByTagName, just use the tag
2. You are only getting the first XmlNode in the XmlNodeCollection by using [0]
3. Since you only have one XmlNode, you are only getting a string result for getting the attribute, not a collection of strings, which you are then trying to enumerate through
4. Your foreach is broken, there is no type for the resulting object

问题中的代码有很多问题:
1. 您在 GetElementsByTagName 中使用 XPath,只需使用标记
2. 您仅使用 [0] 获取 XmlNodeCollection 中的第一个 XmlNode
3. 由于您只有一个 XmlNode,你只得到一个字符串结果来获取属性,而不是一个字符串集合,然后你试图通过
4枚举它。你的 foreach 坏了,结果对象没有类型

Here is a snippet that would work:

这是一个可以工作的片段:

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
}

Or, if you don't need all of the actions and filenames in a collection before you act on them, you could just act on each action/filename in the for loop.

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