我正在尝试按优先级节点对下面的 XML 进行排序,因此 1.0 是最高的,然后它们紧随其后。然而,我尝试的一切都不会返回任何东西。这是我的代码,第一个块是我做的一个空的尝试,第二个块是我的内联尝试,它返回一个空引用。
首先:
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;
第二:
XDocument xdocument = this.BuildXmlDocument((IEnumerable<XElement>)xelementList1.OrderByDescending(x => x.Element("priority")?.Value));
文档:
<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>
答案 0 :(得分:1)
您应该将保存数据(存储)的过程与处理数据的过程分开。这使您的代码:
(我不确定您的 XML 中有什么内容,在其余的答案中,我将其称为 UrlModifications
)
所以你需要两个独立的代码部分,甚至可能是独立的类:
UrlModifications
序列的部分。类似:在 XML 文件中存储一系列 UrlModifications
。可能的扩展:从 Stream
读/写。UrlModifications
序列并按优先级降序排列的部分。是否值得为此创建单独的类,取决于您是否认为有人可能想要重用或更改此代码,或者您是否想要为其编写单元测试等。
首先是类 UrlModification。我认为它会是这样的:
class UrlModification
{
public string Location {get; set;}
public DateTime LastModifiedDate {get; set; }
public FrequencyDescription ChangeFrequency {get; set;}
public decimal Priority {get; set;}
}
FrequencyDescription 是一个枚举。您可以将其更改为字符串,如果有人键入不受支持的值,则可能会出现问题。如果您不想受到 daily / hourly / weekly / ...
等值的限制,请考虑使用 TimeSpan。 Daily
将替换为 24 小时。无论如何,您将需要一种转换方法,因为要对该值执行任何操作,您都需要将单词 Daily
转换为 TimeSpan 24 hours
。
为了读取和写入文件,我将创建一个存储库类(仓库意义上的存储库:您将项目存储在其中,然后您可以从中检索相同的项目,即使您已经重新启动程序。
为了使该类更具可重用性,我不仅会将其保存到文件中,还会将其保存到 Stream 和 TextReader / TextWriter。这也将使单元测试更容易
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);
}
}
Stream 的方法类似。
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());
}
这隐藏了您加载/保存项目的格式。您可以将其更改为 JSON 格式,甚至 CSV。用户(=软件,而不是运营商)不会注意到差异。
如果您对此进行单元测试,您会发现 XML 格式与您的格式不完全相同。修复此问题的最简单方法是将 XML 属性添加到您的类中:
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; }
}
您可能比我更了解 XML,所以我想您会明白要点。
我正在尝试按优先级节点对下面的 XML 进行排序,因此 1.0 是最高的,然后它们紧随其后。
创建存储库后,这将非常简单:
string fileName = ...
UrlModificationRepository repository = new UrlModidificationRepository();
var urlsOrderedByDescendingPriority = repository.Load(fileName)
.OrderByDescending(urlModification => urlModification.Priority);
通过将数据的存储方式与数据处理分离,您使代码更易于理解和单元测试。代码具有高度可重用性和可变性。