我发现确定解析某些XML的最佳方法令人费解。看来他们有很多可能的方式,没有人真正点击过我。
我目前的尝试看起来像这样:
XElement xelement = XElement.Parse(xmlText);
var name = xelement.Element("Employee").Attribute("name").Value;
所以,这很有效。但是如果缺少“Employee”元素或“name”属性,它会抛出异常。我不想抛出异常。
探索一些examples available online,我看到这样的代码:
XElement xelement = XElement.Load("..\\..\\Employees.xml");
IEnumerable<XElement> employees = xelement.Elements();
Console.WriteLine("List of all Employee Names :");
foreach (var employee in employees)
{
Console.WriteLine(employee.Element("Name").Value);
}
这似乎会遇到完全相同的问题。如果“Name”元素不存在,Element()
将返回null
,并且调用Value
属性时出错。
我需要一些像上面第一个代码片段一样的块。是否有一种简单的方法可以使它工作,如果缺少某些数据则不会抛出异常?
答案 0 :(得分:3)
我经常在这种情况下使用扩展方法,因为即使引用为null也可以工作。我使用了一个稍微修改过的版本的扩展方法来自Anders Abel从2012年初开始的非常好的博客文章“Null Handling with Extension Methods”:
public static class XElementExtension
{
public static string GetValueOrDefault(this XAttribute attribute,
string defaultValue = null)
{
return attribute == null ? defaultValue : attribute.Value;
}
public static string GetAttributeValueOrDefault(this XElement element,
string attributeName,
string defaultValue = null)
{
return element == null ? defaultValue : element.Attribut(attributeName)
.GetValueOrDefault(defaultValue);
}
}
如果要在元素或属性不存在时返回“null”:
var name = xelement.Element("Employee")
.GetAttributeValueOrDefault("name" );
如果要在元素或属性不存在时返回默认值:
var name = xelement.Element("Employee")
.GetAttributeValueOrDefault("name","this is the default value");
在for循环中使用:
XElement xelement = XElement.Load("..\\..\\Employees.xml");
IEnumerable<XElement> employees = xelement.Elements();
Console.WriteLine("List of all Employee Names :");
foreach (var employee in employees)
{
Console.WriteLine(employee.GetAttributeValueOrDefault("Name"));
}
答案 1 :(得分:3)
您可以结合使用XAttribute
到string
的显式字符串转换(如果操作数为null,则返回null)和FirstOrDefault
方法:
var name = xelement.Elements("Employee")
.Select(x => (string) x.Attribute("name"))
.FirstOrDefault();
如果没有这样的元素,那将是null(因为序列将为空,FirstOrDefault()
将返回null)或者没有属性的元素(在这种情况下,您将得到一个带有null元素,FirstOrDefault
将返回。)
答案 2 :(得分:2)
你总是可以使用XPath:
string name = xelement.XPathEvaluate("string(Employee/@name)") as string;
这可以是属性的值,如果null
或Employee
不存在,则为@name
。
对于迭代示例:
foreach (XNode item in (IEnumerable)xelement.XPathEvaluate("Employee/Name"))
{
Console.WriteLine(item.Value);
}
XPathEvaluate()
只会在此处选择有效节点,因此您可以确信item
始终为非空。
答案 3 :(得分:0)
一切都取决于您从XML中提取数据后要对数据执行的操作。
您最好查看专为XML处理而设计的语言,例如XSLT和XQuery,而不是使用像C#这样的语言(尽管Linq为您提供了混合的东西)。使用C#或Java,您总是需要做很多工作才能应对XML非常灵活的事实。
答案 4 :(得分:0)
使用原生XmlReader 。如果您的问题是阅读大型 XML 文件而不是允许 XElement 构建对象表示,那么您可以构建类似 Java SAX 解析器的内容流 XML 。
<强>实施例强> http://www.codeguru.com/csharp/csharp/cs_data/xml/article.php/c4221/Writing-XML-SAX-Parsers-in-C.htm