[英]What is the most efficient way to select an XML value based on one of its associative attributes using C#
我有一个类似于这样的XML文档:
<resorts>
<resort location="locationA" email="locationA@somewhere.com"></resort>
<resort location="locationB" email="locationB@somewhere.com"></resort>
<resort location="locationC" email="locationC@somewhere.com"></resort>
<resort location="locationD" email="locationD@somewhere.com"></resort>
</resorts>
我需要在给定特定位置的情况下获取相应的电子邮件地址,而我正在使用的代码是:
XmlDocument doc = new XmlDocument();
doc.Load(xml);
XmlElement xmlRoot = doc.DocumentElement;
XmlNodeList xmlNodes = xmlRoot.SelectNodes("/resorts/resort");
foreach(XmlNode element in xmlNodes)
{
foreach (XmlAttribute attribute in element.Attributes)
{
switch (attribute.Name)
{
case "location":
if (attribute.Value.ToLower() == location.ToLower())
{
loc = attribute.Value;
locationIdentified = true;
}
break;
case "email":
if (locationIdentified)
{
if(!emailIdentified)
{
email = attribute.Value;
var recipientList = new Dictionary<string, string>() { { "emailrecipients", email } };
emailRecipients.Add(recipientList);
emailIdentified = true;
}
}
break;
}
}
}
return recipients;
但我并不十分关心迭代方法,而是希望用更少的代码更精简。
类似于linq表达式的东西是理想的,但我通常不需要处理很多XML数据,所以我在这方面有点新手; 但我知道必须有一种更好的方法来从XML中检索数据。
我需要做的是获取特定位置的电子邮件地址; 预先知道位置。
如果没有像我在这里所做的那样进行显式迭代,那么最有效的方法是什么?
这个问题并不是特别关于“ 如何使用 ”替代选项,而是“解决这个问题的更简化方法 ”。 但是,正如我所说; 因为我是XML的新手,所以提供任何提议的替代方案的例子会很好
谢谢
如果您使用Linq to XML,您的查询可能如下所示:
var query=root.Descendants("resort").Where(e=>e.Attribute("location").Value.ToLower()==location.ToLower())
.Select(e=>e.Attribute("email"));
如果只有一个位置,您可以使用FirstOrDefault
扩展方法来获取它:
var result=query.FirstOrDefault();
octavioccl的答案是正确的,但是如果你有理由坚持使用XmlDocument
而不是切换到Linq到XML(也许这是一个已经大量致力于旧XML类的大项目,并且没有人想要跨越流),这将是工作:
string location = "locationC";
string xpath = "/resorts/resort[@location='" + location + "']/@email";
var address = doc.SelectNodes(xpath).Cast<XmlAttribute>()
.Select(attr => attr.Value).SingleOrDefault();
如果你可以使用C#6功能,这更整洁:
var address = doc.SelectSingleNode(xpath)?.Value;
如果你需要它是盲目的,我想你可能会被困在这个:
string xpath = "/resorts/resort[translate(@location, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')='"
+ location.ToLower() + "']/@email";
XPath 2.0中有一个lower-case()
函数,但SelectNodes
似乎正在实现XPath 1.0。 那个凌乱的translate()
调用是通常的解决方法。
很难说什么是最有效的,但你可以考虑使用XPath来遍历XML而不必迭代。
以下是一些示例:
https://msdn.microsoft.com/en-us/library/ms256086(v=vs.110).aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.