如何查找xml元素的最小值和最大值

时间:2015-11-25 20:06:45

标签: c# xml xpath

任何人都可以帮我解决这个问题吗?

我必须根据费用值找到最小和最大月份:

<?xml version="1.0" encoding="UTF-8"?>
<shop>
   <month>Jan</month>
   <expense>2520,50€</expense>
   <month>Feb</month>
   <expense>2900,00€</expense>
   <month>Mar</month>
   <expense>1000,00€</expense>
   <month>Apr</month>
   <expense>1520,00€</expense>
   <month>May</month>
   <expense>500,00€</expense>
   <month>Jun</month>
   <expense>1250,50€</expense>
   <month>Jul</month>
   <expense>300,00€</expense>
   <month>Aug</month>
   <expense>0,00€</expense>
 </shop>

我已经尝试过XPath但没有成功......

XmlDocument doc = new XmlDocument();
doc.Load("XML/despesas.xml");

XmlNode node = doc.SelectSingleNode("//shop/expense[not(. <=../preceding-sibling::expense) and not(. <=../following-sibling::expense)]");
int min = Convert.ToInt32(node.Value);

3 个答案:

答案 0 :(得分:2)

您需要阅读xml,然后找到费用的最小值/最大值以及相应的月份。

这是一种O(n)方法,用于查找具有最低/最高费用的月份。

var xmlString = File.ReadAllText(@"C:\YourDirectory\YourFile.xml");

var xDoc = XDocument.Parse(xmlString);
var months = xDoc.Descendants("month");
var expenses = xDoc.Descendants("expense");

var cultureInfo = new CultureInfo("fr-FR");

decimal maxExp = decimal.MinValue;
decimal minExp = decimal.MaxValue;
string maxExpMonth = string.Empty; //=> "Feb"
string minExpMonth = string.Empty; //=> "Aug"
for (int i = 0; i < expenses.Count(); i++)
{
    var exp = decimal.Parse(expenses.ElementAt(i).Value, NumberStyles.Currency, cultureInfo);
    if (exp > maxExp)
    {
        maxExp = exp;
        maxExpMonth = months.ElementAt(i).Value;
    }
    if (exp < minExp)
    {
        minExp = exp;
        minExpMonth = months.ElementAt(i).Value;
    }
}

答案 1 :(得分:0)

您可以使用XElement然后获取所有费用元素。要获得整数值,您需要删除货币符号,如下所示。

var parsedXml = XElement.Parse(xmlToParse);
var expenses = (from e1 in parsedXml.Elements("expense")
                select int.Parse(Regex.Replace(e1.Value,"[^0-9]", string.Empty))).ToList();
var minValue = expenses.Min();
var maxValue =  expenses.Max();

答案 2 :(得分:0)

我建议使用Linq to XML而不是使用XPath。然后,您可以将元素解析到内存中并更好地查询它们。您可以使用以下示例获取最小值和最大值:

void Main()
{
    const string content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + 
                                "<shop>" + 
                                   "<month>Jan</month>" + 
                                   "<expense>2520,50€</expense>" + 
                                   "<month>Feb</month>" + 
                                   "<expense>2900,00€</expense>" + 
                                   "<month>Mar</month>" + 
                                   "<expense>1000,00€</expense>" + 
                                   "<month>Apr</month>" + 
                                   "<expense>1520,00€</expense>" + 
                                   "<month>May</month>" + 
                                   "<expense>500,00€</expense>" + 
                                   "<month>Jun</month>" + 
                                   "<expense>1250,50€</expense>" + 
                                   "<month>Jul</month>" + 
                                   "<expense>300,00€</expense>" + 
                                   "<month>Aug</month>" + 
                                   "<expense>0,00€</expense>" + 
                                 "</shop>";
    var doc = XDocument.Parse(content);
    var elements = doc.Element("shop")  // Element shop
                        .Elements()     // All elements under shop
                        .Select((x, i) => new { Index = i, Element = x }) // Get index for grouping
                        .GroupBy(x => x.Index / 2)  // Group by index so that month and expense element are contained in a group
                        .Select(x => new { Month = x.ElementAt(0).Element.Value, Expense = decimal.Parse(x.ElementAt(1).Element.Value, System.Globalization.NumberStyles.Any) })    // Parse into anonymous type
                        .OrderBy(x => x.Expense)    // Order by expense
                        .ToArray(); // Execute query
    var min = elements.FirstOrDefault();
    var max = elements.LastOrDefault();
}

首先,将XML加载到XDocument中。在此示例中,我解析了字符串,但您也可以使用Load方法来读取文件。

查询有点复杂;首先,您获得shop下的所有元素。然后,您可以将它们选择为也包含元素索引的匿名类型。该索引用于构建包含月份和费用的组。

然后,创建一个新的匿名类型,其中包含单个对象中的月份和费用(作为小数)。请注意,将费用值解析为小数是依赖于文化的。在示例中,我没有指定文化,但在现实世界的场景中可能需要这样做。结果列表按Expense按升序排序。

分别使用FirstOrDefaultLastOrDefault,您可以检索最小值和最大值。