繁体   English   中英

使用C#基于其关联属性之一选择XML值的最有效方法是什么?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM