简体   繁体   English

如何找到xml元素的Min和Max值

[英]How to find Min and Max value of xml element

Can anyone help me with this problem? 任何人都可以帮我解决这个问题吗?

I have to find the Min and Max months according to expenses values: 我必须根据费用值找到最小和最大月份:

<?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>

I already tried with XPath but without success... 我已经尝试过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);

You need to read the xml, then find the Min/Max of the expenses and the corresponding month. 您需要读取xml,然后查找费用的最小值/最大值以及相应的月份。

Here is one O(n) way to find the Month with Min/Max expense. 这是一种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;
    }
}

You could XElement and then getall the expense elements. 您可以使用XElement然后获取所有费用元素。 To get just the interger value, you would need to remove the currency symbol as shown below. 要获得整数值,您需要删除货币符号,如下所示。

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();

Instead of using XPath, I suggest to use Linq to XML . 我建议使用Linq to XML ,而不是使用XPath。 You can then parse the elements into memory and query them a lot better. 然后,您可以将元素解析到内存中并更好地查询它们。 You can use the following sample to get the min and the max values: 您可以使用以下示例来获取最小值和最大值:

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();
}

At the beginning, you load the XML into an XDocument. 首先,将XML加载到XDocument中。 In this sample, I parse the string, but you can also use the Load method to read a file. 在此示例中,我解析了字符串,但您也可以使用Load方法来读取文件。

The query is a bit complicated; 查询有点复杂; first, you get all the elements under shop . 首先,你得到了shop所有元素。 You then select them into an anonymous type that also contains the index of the element. 然后,您可以将它们选择为也包含元素索引的匿名类型。 The index is used to build groups that contain month and expense. 该索引用于构建包含月份和费用的组。

Then, a new anonymous type is created that contains both month and expense (as a decimal) in a single object. 然后,创建一个新的匿名类型,其中包含单个对象中的月份和费用(作为小数)。 Please note that parsing the value of expense into a decimal is culture dependent. 请注意,将费用值解析为小数是依赖于文化的。 In the sample, I do not specify a culture, but this might be required in a real world scenario. 在示例中,我没有指定文化,但在现实世界的场景中可能需要这样做。 The resulting list is sorted by Expense in ascending order. 结果列表按Expense按升序排序。

By using FirstOrDefault and LastOrDefault respectively, you can retrieve the min and max values. 通过分别使用FirstOrDefaultLastOrDefault ,您可以检索最小值和最大值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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