【问题标题】:How to check the values of attributes are in ascending order and also find duplicates?如何检查属性的值是否按升序排列并找到重复项?
【发布时间】:2018-04-22 07:15:55
【问题描述】:

这是一个示例 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>

如何检查节点&lt;book&gt;中属性id的值是否按升序排列,同时以最简单的方式查找其中是否存在重复值。 我做了

static void Main(string[] args)
{

    XDocument myfile = XDocument.Parse(File.ReadAllText(@"D:\sample_xml.xml"));
    var check = myfile.Descendants("book").Select(a => a.Attribute("id").Value.Substring(2)).ToArray();

    if (IsSortedAscending(check))
    {
        Console.WriteLine("Sorted in Ascending order");
    }
    else
    {
        Console.WriteLine("Check Sequence");
    }

    Console.ReadLine();
}


public static bool IsSortedAscending(string[] arr)
{
    for (int i = arr.Length - 2; i >= 0; i--)
    {
        if (arr[i].CompareTo(arr[i + 1]) > 0)
        {
            return false;
        }
    }
    return true;
}

但它不考虑重复值...我该怎么做?

另外,是否可以在属性 id 中找到缺失值(如果有),例如如果有 bk109 而下一个是 bk112 则程序将显示 bk110bk111 缺失。

【问题讨论】:

  • 使用 XML 反序列化将 xml 数据加载到对象,然后使用 LINQ。 stackoverflow.com/questions/18340427/…
  • @RudreshaParameshappa:为什么要反序列化? LINQ to XML 使这变得微不足道。
  • @DaisyShipton 哦,是的,谢谢,我忘了..

标签: c# xml


【解决方案1】:

您已经快到了 - “严格升序,无重复”和“升序,允许重复”之间的唯一区别是比较结果为 0 时的操作(即值与前一个相同)一)。

如果比较的结果是&gt;= 0 而不仅仅是&gt; 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;
}

(您也可以使用SkipZip 作为成对比较元素的替代方法,但这是一个稍微不同的问题。)

请注意,如果您的号码长度不同,目前您的代码可能会失败。例如,考虑 ID“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 丢失了,诚然。

【讨论】:

  • 但是如何检查序列中的缺失值
  • @TamalBanerjee:啊,我错过了那部分。我将编辑 - 以及数字的一个方面......
  • @TamalBanerjee:现在看看。
【解决方案2】:

我只会对元素进行排序并放入字典:

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

【讨论】:

  • 你为什么使用“publish_date”?我只需要查询book 节点即可
  • 你叫什么重复?通常带有您想要最新的重复项,所以我进行了排序。
  • 我不想更新文件,我只想检查id的值是否按升序排列,以及节点book是否有重复的id值。 ..
猜你喜欢
  • 1970-01-01
  • 2018-03-30
  • 2013-10-11
  • 2015-12-27
  • 2018-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多