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
C# get values from xml attributes
提问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 Action
and FileName
properties:
您可以使用LINQ to XML。以下查询返回具有Action
和FileName
属性的强类型项集合:
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
GetElementsByTagName
will 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 SelectNodes
instead.
如果要在提供 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 循环中的每个动作/文件名采取行动。