[英]Having trouble sorting an Xelement with LINQ
I am trying to sort my XML below by the priority node, so the 1.0 is the highest and then they follow after.我正在尝试按优先级节点对下面的 XML 进行排序,因此 1.0 是最高的,然后它们紧随其后。 However everything I try wont return anything.
但是我尝试的一切都不会返回任何东西。 Here is my code, the first chunk was a try I did that is just empty, the second chunk is my inline try that returns a null reference.
这是我的代码,第一个块是我所做的尝试,它只是空的,第二个块是我的内联尝试,它返回 null 引用。
First:第一的:
XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";
IEnumerable<XElement> list =
from el in xelementList1.Elements(ns + "url")
let priority = (int)el.Element(ns + "priority")
orderby priority descending
select el;
Second:第二:
XDocument xdocument = this.BuildXmlDocument((IEnumerable<XElement>)xelementList1.OrderByDescending(x => x.Element("priority")?.Value));
Document:文档:
<urlset xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https:///</loc>
<lastmod>2021-03-15</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https:///404/</loc>
<lastmod>2021-04-22</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https:///500/</loc>
<lastmod>2021-04-22</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https:///avalon-brochures/</loc>
<lastmod>2021-04-27</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https:///contact-us/</loc>
<lastmod>2021-04-27</lastmod>
<changefreq>daily</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https:///cors-test/</loc>
<lastmod>2021-03-15</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
You should separate the process of persisting your data (storage) from the process of handling the data.您应该将持久化数据(存储)的过程与处理数据的过程分开。 This makes your code:
这使您的代码:
(I'm not sure what's in your XML, In the rest of the answer I'll call this UrlModifications
) (我不确定您的 XML 中有什么,在答案的 rest 中我称之为
UrlModifications
)
So you need two separate parts of code, maybe even separate classes:所以你需要两个单独的代码部分,甚至可能是单独的类:
UrlModifications
.UrlModifications
序列的部件。 Similar: store a sequence of UrlModifications
in an XML file.UrlModifications
存储在 XML 文件中。 Possible extensions: read/write from a Stream
.Stream
读/写。UrlModifications
and orders them by descending priority.UrlModifications
并按优先级降序排列它们的部分。 Whether it is worth to make separate classes for this, depends on whether you think someon might want to reuse this code, or change it, or whether you want to write unit tests for it, etc.是否值得为此创建单独的类,取决于您是否认为某人可能想要重用此代码或更改它,或者您是否想为它编写单元测试等。
First the class UrlModification.首先是class UrlModification。 I think it will be something like this:
我认为它会是这样的:
class UrlModification
{
public string Location {get; set;}
public DateTime LastModifiedDate {get; set; }
public FrequencyDescription ChangeFrequency {get; set;}
public decimal Priority {get; set;}
}
FrequencyDescription is an enum. FrequencyDescription 是一个枚举。 You can change it to a string, which might give problems if someone types un unsupported value.
您可以将其更改为字符串,如果有人键入不受支持的值,这可能会出现问题。 If you don't want to be limited by values like
daily / hourly / weekly /...
, consider to use a TimeSpan.如果您不想受到
daily / hourly / weekly /...
等值的限制,请考虑使用 TimeSpan。 Daily
will be replaced by 24 hours. Daily
将改为 24 小时。 You will need a conversion method anyway, because to do anything with this value, you'll need to convert the word Daily
into TimeSpan 24 hours
.无论如何,您将需要一个转换方法,因为要使用此值执行任何操作,您需要将单词
Daily
转换为TimeSpan 24 hours
。
To Read and Write this to a file, I'll create a repository class (Repository in the sense of a warehouse: you store items in it, and later you can retrieve the same item from it, even if you have restarted the program.要读取并将其写入文件,我将创建一个存储库 class(仓库意义上的存储库:您将项目存储在其中,然后您可以从中检索相同的项目,即使您已重新启动程序。
To make the class a bit more reusable, I will not only save it to a file, but also to a Stream and a TextReader / TextWriter.为了使 class 更具可重用性,我不仅将其保存到文件中,还将保存到 Stream 和 TextReader / TextWriter 中。 This will also make the unit test easier
这也将使单元测试更容易
class UrlModificationRepository
{
public IList<UrlModifiction> Load(string fileName)
{
using (var textReader = File.OpenText(fileName))
{
return Load(textReader);
}
}
public IList<UrlModification> Load(System.IO.TextReader textReader)
{
return (UrlModification[]) serializer.Deserialize(textReader);
}
}
The method for a Stream is similar. Stream 的方法类似。
The Save methods are also one-liners: Save 方法也是单行的:
public void Save(string fileName, IEnumerable<UrlModification> urlModifications)
{
using (var textWriter = File.CreateText(fileName))
{
this.Save(textWriter, urlModifications);
}
}
public void Save(TextWriter textWriter, IEnumerable<UrlModification> urlModifications)
{
serializer.Serialize(textWriter, urlModifications.ToArray());
}
This has hidden the format in which you load / save items.这隐藏了您加载/保存项目的格式。 You can change it in JSON format, or even CSV.
您可以将其更改为 JSON 格式,甚至 CSV。 Users (=software, not operators) won't notice the difference.
用户(=软件,而不是操作员)不会注意到差异。
If you unit test this, you will see that the XML format is not exactly the same format as yours.如果您对此进行单元测试,您将看到 XML 格式与您的格式不完全相同。 The easiest way to repair this is to add XML attributes to your class:
修复此问题的最简单方法是将 XML 属性添加到 class 中:
public class UrlModification
{
[XmlElement("Loc")]
public string Location { get; set; }
[XmlElement("LastMod", DataType = "date")]
public DateTime LastModifiedDate { get; set; }
public FrequencyDescription ChangeFrequency { get; set; }
public decimal Priority { get; set; }
}
You probably know XML better than I do, so I guess you'll get the gist.你可能比我更了解 XML,所以我想你会明白要点的。
I am trying to sort my XML below by the priority node, so the 1.0 is the highest and then they follow after.
我正在尝试按优先级节点对下面的 XML 进行排序,因此 1.0 是最高的,然后它们紧随其后。
Once you've created the repository, this will be very easy:创建存储库后,这将非常容易:
string fileName = ...
UrlModificationRepository repository = new UrlModidificationRepository();
var urlsOrderedByDescendingPriority = repository.Load(fileName)
.OrderByDescending(urlModification => urlModification.Priority);
By separating how the data is stored from the data processing, you made the code easier to understand and unit test.通过将数据的存储方式与数据处理分开,您使代码更易于理解和单元测试。 The code is highly reusable and changeable.
该代码具有高度可重用性和可变性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.