C# 如何检查属性值是否按升序排列并查找重复项?

C# 如何检查属性值是否按升序排列并查找重复项?,c#,xml,C#,Xml,下面是一个示例xml <?xml version="1.0"?> <catalog> <book id="bk101"> <author>Gambardella, Matthew</author> <title>XML Developer's Guide</title> <genre>Computer</genre>

下面是一个示例xml

<?xml version="1.0"?>
<catalog>
    <book id="bk101">
        <author>Gambardella, Matthew</author>
        <title>XML Developer's Guide</title>
        <genre>Computer</genre>
        <price>44.95</price>
        <publish_date>2000-10-01</publish_date>
        <description>An in-depth look at creating applications
        with XML.</description>
    </book>
    <book id="bk102">
        <author>Ralls, Kim</author>
        <title>Midnight Rain</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2000-12-16</publish_date>
        <description>A former architect battles corporate zombies,
            an evil sorceress, and her own childhood to become queen
        of the world.</description>
    </book>
    <book id="bk102">
        <author>Corets, Eva</author>
        <title>Maeve Ascendant</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2000-11-17</publish_date>
        <description>After the collapse of a nanotechnology
            society in England, the young survivors lay the
        foundation for a new society.</description>
    </book>
    <book id="bk103">
        <author>Corets, Eva</author>
        <title>Oberon's Legacy</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2001-03-10</publish_date>
        <description>In post-apocalypse England, the mysterious
            agent known only as Oberon helps to create a new life
            for the inhabitants of London. Sequel to Maeve
        Ascendant.</description>
    </book>
</catalog>
但它不能解释重复的值…我该怎么做


此外,是否有可能在属性id中找到缺失的值(如果有)。如果存在bk109,下一个是bk112,那么程序将显示bk110bk111缺失。

你已经差不多到了-两者之间的唯一区别是“严格升序,无重复项”和“升序,允许重复项”是比较结果为0(即该值与上一个值相同)时所做的操作

如果比较结果是
>=0
,而不仅仅是
>0
,则只需更改
IsSortedAscending
方法返回
false

public static bool IsSortedAscending(string[] arr)
{
    for (int i = arr.Length - 2; i >= 0; i--)
    {
        // Fail if this ID is equal to or bigger than the next one.
        if (arr[i].CompareTo(arr[i + 1]) >= 0)
        {
            return false;
        }
    }
    return true;
}
(您也可以使用
Skip
Zip
作为成对比较元素的替代方法,但这是一个稍微不同的问题。)

注意,如果你的代码长度不同,你的代码可能会失败。例如,考虑IDS“BK99”和“BK100”。这将把“99”和“100”作为字符串进行比较,并决定“99”在“100”之后出现。 如果您的ID总是后跟一个整数的“bk”,我会提前解析它们:

var ids = myfile.Descendants("book")
                .Select(a => a.Attribute("id").Value.Substring(2))
                .Select(id => int.Parse(id))
                .ToArray();
然后将方法更改为接受
int[]
而不是
string[]

在这一点上,检查“缺失”ID也容易得多-在字符串形式中,没有“缺失”ID的真正概念,因为您可能有“bk101”、“bk101a”、“bk101c”-“bk101b”缺失吗?如果是,那么“bk101aa”呢?对于整数,就简单得多

获得整数ID数组后,可以使用数组的长度检查是否缺少任何值:

if (ids.Length > 0 ids.Length - 1 != ids.Last() - ids.First())
{
    Console.WriteLine("At least one ID is missing");
}

无可否认,这不会告诉您缺少哪个ID。

我只会对元素进行排序,然后放入字典:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            XElement catalog = doc.Root;

            Dictionary<string, List<XElement>> dict = catalog.Elements("book")
                .OrderBy(x => (string)x.Attribute("id"))
                .ThenBy(x => (DateTime)x.Element("publish_date"))
                .GroupBy(x => (string)x.Attribute("id"), y => y)
                .ToDictionary(x => x.Key, y => y.ToList());
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
XDocument doc=XDocument.Load(文件名);
XElement目录=文档根目录;
字典dict=catalog.Elements(“书”)
.OrderBy(x=>(字符串)x.Attribute(“id”))
.ThenBy(x=>(DateTime)x.Element(“发布日期”))
.GroupBy(x=>(字符串)x.Attribute(“id”),y=>y)
.ToDictionary(x=>x.Key,y=>y.ToList());
}
}
}

使用XML反序列化将XML数据加载到对象上,然后使用LINQ。@RudArameshappa:为什么要麻烦进行反序列化?LINQ到XML使这变得微不足道。@DaisyShipton哦,是的,谢谢,我忘记了。但是我如何检查sequence@TamalBanerjee:啊,我错过了那部分。我将编辑-以及数字的一个方面…@Tam阿尔巴纳吉:现在看看。你为什么用“发布日期”"? 我只需要查询
书籍
节点,其他什么都不需要。你称之为复制品是什么?通常,对于重复项,您希望获取最新版本,因此我进行了排序。我不希望更新文件,我只想检查
id
的值是否按升序排列,以及节点
book
是否有重复的
id
值。。。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            XElement catalog = doc.Root;

            Dictionary<string, List<XElement>> dict = catalog.Elements("book")
                .OrderBy(x => (string)x.Attribute("id"))
                .ThenBy(x => (DateTime)x.Element("publish_date"))
                .GroupBy(x => (string)x.Attribute("id"), y => y)
                .ToDictionary(x => x.Key, y => y.ToList());
        }
    }
}