【问题标题】:XMLdocument SortXML文档排序
【发布时间】:2012-08-24 09:55:46
【问题描述】:

我已经知道如何在正确的结构中将节点附加到我的 rss 文档中。我现在需要按 pubDate 顺序对其进行排序,然后输出到屏幕。查看在线示例,我发现了很多 XDocument 和 Linq 的东西,但 XmlDocument 没有。摸不着头脑是放弃我拥有的代码并根据此处的建议在 XDocument 中解决问题,还是继续使用 XMLDocument 并找出一种排序方法。

使用 XMLDocument,我的代码可以完全按照我的意愿工作,只需要在我的提要在屏幕上显示时按照 pubDate 顺序进行排序。所以我想我会暂时坚持这个。我找到了这篇文章http://support.microsoft.com/kb/555060 和某人在 Stack Overflow 中发布的 xslt,但我不知道如何从我的代码中调用“XmlHelperFunctions”。 XSLT 是我拥有的最简单的选择,还是有更简单的方法?

这是我的代码:

    XmlDocument xmlDoc = new XmlDocument();

    xmlDoc.LoadXml(rssFeed.ToString());

    XmlNodeList nl = xmlDoc.SelectNodes("/rss/channel/item");

    foreach (XmlNode xn in nl)
    {
        string title = xn["title"].InnerText;
        string link = xn["link"].InnerText;
        string desc = xn["description"].InnerText;
        string auth = xn["author"].InnerText;
        string pdate = xn["pubDate"].InnerText;

        XmlElement itemnode = xmlDoc.CreateElement("item");

        itemnode.InnerXml = "<title></title><link></link><description></description><author></author><pubDate></pubDate>";
        itemnode["title"].InnerText = title;
        itemnode["link"].InnerText = link;
        itemnode["description"].InnerText = desc;
        itemnode["author"].InnerText = auth;
        itemnode["pubDate"].InnerText = pdate;

        xmlDoc.DocumentElement.SelectNodes("/rss/channel")[0].AppendChild(itemnode);
    }

    // Output to screen
    xmlDoc.Save(Response.Output);

我的 RSS 源

<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
<channel>
<title>My RSS Feed</title>
<link>http://www.mylink.aspx</link>
<description>
</description>
<item>
  <title>Top marks</title>
  <link>http://www.mymarks.aspx</link>
  <description>
  &lt;p&gt;description field here&lt;/p&gt;
  </description>
  <author>Viv</author>
  <pubDate>Thu, 16 Aug 2012 12:10:54 GMT</pubDate>
</item>
<item>
  <title>Costa Coffee</title>
  <link>http://www.Costa.aspx</link>
  <description>
  &lt;p&gt;Costa Coffee have special offers.&lt;/p&gt;
  </description>
  <author>Mike</author>
  <pubDate>Thu, 23 Aug 2012 15:55:53 GMT</pubDate>
</item>
<item>
  <title>Celebrate success</title>
  <link>http://www.Celebrate.aspx</link>
  <description>
  &lt;p&gt;Lets all celebrate &lt;/p&gt;
  </description>
  <author>Viv</author>
  <pubDate>Thu, 22 Aug 2012 09:10:21 GMT</pubDate>
</item>
</channel>
</rss>

【问题讨论】:

标签: c# xmldocument


【解决方案1】:

您可以使用Linq to XML 快速轻松地完成此操作。

如果您使用 XElement.Parse(...) 解析您的 XML,那么您可以使用 OrderBy 或 OrderByDescending 函数并很容易地更改内容。 这是一个简化的例子:

XElement element = XElement.Parse(@"
<rss>
<channel>
<item title='something' pubDate='22/11/2012'/>
<item title='something2' pubDate='24/03/2012'/>
<item title='something3' pubDate='10/02/2010'/>
<item title='something4' pubDate='22/01/2011'/>
</channel>
</rss>");

var elements = element.Element("channel")
                .Elements("item")
                .OrderBy<XElement, DateTime>(e => DateTime.ParseExact(e.Attribute("pubDate").Value, "dd/MM/yyyy", null))
                .Select(e => new XElement("item",
                    new XElement("title", e.Attribute("title").Value),
                    new XElement("pubDate", e.Attribute("pubDate").Value))); // Do transform here.

            element.Element("channel").ReplaceAll(elements);

            Console.Write(element.ToString());

XML 不会和你的一样,但希望它能让你知道你可以做什么。您可以将 XElement 和 XAttribute 对象指定为新 XML 的内容,这会输出以下内容:

<rss>
  <channel>
    <item>
      <title>something3</title>
      <pubDate>10/02/2010</pubDate>
    </item>
    <item>
      <title>something4</title>
      <pubDate>22/01/2011</pubDate>
    </item>
    <item>
      <title>something2</title>
      <pubDate>24/03/2012</pubDate>
    </item>
    <item>
      <title>something</title>
      <pubDate>22/11/2012</pubDate>
    </item>
  </channel>
</rss>

我希望这是有用的。

【讨论】:

  • 嗨,Balthy,谢谢。我似乎在智能感知中尝试使用 .OrderBy 时出错 - “....XElement 不包含 OrderBy 的定义”。
  • 我希望你需要确保你有一个“使用 System.Linq;”代码文件顶部的语句。这是包含大部分扩展方法(包括 OrderBy)的主要 Linq 命名空间
  • 嗯...我只是在默认的控制台应用程序中写的。您是否拥有以下所有 using 语句?使用系统;使用 System.Linq;使用 System.Xml.Linq;
  • 是的,我得到的代码与在 .cs 文件中输入的代码完全相同。 Intellisense 只是不喜欢那行 "e => DateTime.ParseExact...
  • 抱歉,我想不出哪里出了问题。您使用的是什么版本的 VS 和 .NET?这是在 2010 年和 4.0.您可以尝试从 OrderBy 方法中删除类型参数,因为它们可以被隐式解析。或者您可以尝试按表达式排序,看看是否可以使任何表达式起作用...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 2013-04-18
相关资源
最近更新 更多