【问题标题】:Parsing a feed in C#在 C# 中解析提要
【发布时间】:2014-07-29 18:21:59
【问题描述】:

我在解析 C# 中的提要时遇到问题。

我无法让提要的作者更改代码,所以我必须处理它。

我尝试将提要作为 URL 直接传递到 XmlDocument 对象,或者使用 WebClient 作为文本获取它,修剪它以删除似乎由于某种原因放在它前面的任何空间,然后使用 LoadXML 方法加载它。

您可以在此处查看提要示例 > http://scotjobsnet.co.uk.ni.strategiesuk.net/testfeed.xml

我无法通过任何一个

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(feedURL);

或者用字符串。

XmlDocument xmlDoc = new XmlDocument();
string feedAsString = "";
// get from web as string
var webClient = new WebClient();

// Tell them who we are for white listing
webClient.Headers.Add("user-agent", "Mozilla/5.0 (compatible; Job Feed Importer;)");

// fetch feed as string
var content = webClient.OpenRead(feedURL);
var contentReader = new StreamReader(content);
var rssFeedAsString = contentReader.ReadToEnd();
rssFeedAsString = rssFeedAsString.Trim(); // remove any white space beore the feed
xmlDoc.LoadXml(feedAsString);

我得到的错误是:

Root element is missing.
Could not extract first items from feed string; Error The element with name 'jobs' and namespace '' is not an allowed feed format.

我想使用 xpath /jobs/job/ 循环通过提要节点。

我之前解析过这样的提要,XmlDocument 只传入一个 URL,如果不是,则传入一个字符串。

我正在考虑使用正则表达式来循环使用<job>[\s\S]+></job> 类型表达式的提要。

但我更愿意使用标准方法。

由于我无法更改提要,任何人都可以告诉我提要有什么问题以及我解析它的方式。原谅我使用 var 我只是被编造了一段代码来解析来自使用它的示例的提要。我在其他任何地方都使用强类型,一旦我开始工作就会转换它。

任何帮助将不胜感激。

谢谢

【问题讨论】:

    标签: c# .net xml rss feed


    【解决方案1】:

    编辑:您当前的代码失败的原因很简单——您正在尝试解析一个空字符串:

    string feedAsString = "";
    ...
    var rssFeedAsString = contentReader.ReadToEnd();
    rssFeedAsString = rssFeedAsString.Trim();
    xmlDoc.LoadXml(feedAsString);
    

    您永远不会将 feedAsString 设置为新值 - 但您将获取文本为 rssFeedAsString。这是两个不同的变量。

    也就是说,我会使用完全不同的方法。我认为不需要修剪等 - 或使用 XPath,或通过 RSS 阅读器传递它(假设它不是 RSS)。唯一棘手的部分是显式指定 User-Agent 标头,否则服务器会拒绝请求。

    我个人会使用 LINQ to XML,这似乎很好:

    using System;
    using System.Net;
    using System.Xml.Linq;
    
    class Test
    {
        static void Main()
        {
            string text;
            using (var webClient = new WebClient())
            {
                string url = "http://scotjobsnet.co.uk.ni.strategiesuk.net/testfeed.xml";
                webClient.Headers.Add("user-agent", "Mozilla/5.0");
                text = webClient.DownloadString(url);
            }
            var doc = XDocument.Parse(text);
            foreach (var job in doc.Root.Elements("job"))
            {
                Console.WriteLine(job);
            }
        }
    }
    

    【讨论】:

    • 您好,但是如果您在示例中注意到我在将 XML 下载作为字符串传递到 XmlDocument 之前将用户代理设置为字符串。有什么区别?
    • @MonkeyMagix:这可能是由于字符编码 - 例如,您假设它是 UTF-8。从根本上说,我只是使用了一种更简单的方法来获取数据。我们可以更详细地查看问题所在,但我会坚持使用简单、有效的代码 :)
    • 好的,所以我习惯于使用 xpath 解析提要并使用 foreach(childNodes 中的 XmlNode 子节点)和 if(child.node.innerText == "jobtitle") - 那会是什么等效于使用 var 作业?我有需要在数组中检查的字段名称,因此我需要检查 /job/jobs/ 中的每个节点,例如 jobTitle、jobRef、jobDesc - 并保存它们。另外,为什么现在每个人都转向使用 var 而不是强类型?
    • @MonkeyMagix:是什么让你认为var 不是强类型的?这只是 implicit 而不是 explicit 类型的问题。不过,听起来您应该阅读有关 LINQ to XML 的教程,因为您的很多问题都会在那里得到解答。 (不确定您对 jobRef 的含义,因为它没有出现在示例文档中 - 您通常应该使用元素名称,这在 LINQ to XML 中非常容易。)
    • 只是我正在编写一个从 Betfair SOAP 到 JSON 的转换项目,现在一切,甚至字符串、整数和其他对象都与 var 一起使用。您不能将 var 从方法传递到方法,并且我已经阅读了很多反对它的文章。我不是专家,我只是想知道为什么人们会使用 var WebClient = new WebClient() 而不是 WebClient WebClient = new WebClient。 JobRef、JobTitle 等是我们数据库中的所有字段名称。我有一个映射表,它将它们在 XML 中的节点名称映射到我们正确的字段名称。所以我需要在 XML 中获取节点,但要保存正确的 FieldName。
    【解决方案2】:

    我使用了以下解决方案,请看一下:

            XmlDocument xdoc = new XmlDocument();
            xdoc.Load("http://scotjobsnet.co.uk.ni.strategiesuk.net/testfeed.xml");
            if (xdoc != null)
            {
                XmlElement root = xdoc.DocumentElement;
                XmlNodeList xNodelst = root.SelectNodes("job");
                foreach (XmlNode node in xNodelst)
                {
                    string location = node.SelectSingleNode("location").InnerText;
                    Response.Write("<br/> location = " + location);
                }
            }
    

    【讨论】:

    • 谢谢,这正是我所需要的,同时确保我添加了一个用户代理(因为我禁止空白用户代理)以防止脚本小子抓取。另外,我仍然可以使用我现有的代码 node.name 和 node.innerText 来获取值,然后从我的表中获取正确的映射以保存到数据库。谢谢
    • 嗨,我想你不知道我该如何解决编码问题,因为当我循环遍历子节点时,£符号返回为 10,001 英镑,例如 CandidateSalary。我认为 .Load 方法上可能有一个 Encoding.UTF8 选项,但没有。 XML 文件保存为 UTF-8。我将子节点数据通过管道传输到的文件是 UTF-8,我在将其传输到文件时使用 Encoding.UTF8(尝试使用和不使用)。
    【解决方案3】:

    这对我有用。我用的是下载字符串。

            var feedURL = "http://scotjobsnet.co.uk.ni.strategiesuk.net/testfeed.xml";
            XmlDocument xmlDoc = new XmlDocument();
            string feedAsString = "";
            // get from web as string
            var webClient = new WebClient();
    
            // Tell them who we are for white listing
            webClient.Headers.Add("user-agent", "Mozilla/5.0 (compatible; Job Feed Importer;)");
    
            // fetch feed as string
            var content = webClient.DownloadString(feedURL);
            xmlDoc.LoadXml(content);
            var jobs = xmlDoc.GetElementsByTagName("job");
            foreach (var job in jobs)
            {
               //Loop through Jobs 
            }
    

    【讨论】:

      【解决方案4】:

      听起来很傻,试试Html Agility Pack。它旨在处理格式不太好的输入,您可以使用类似 XPath 的表达式来遍历树。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-01-30
        • 2012-10-19
        • 2012-02-18
        • 1970-01-01
        • 1970-01-01
        • 2015-10-23
        • 1970-01-01
        相关资源
        最近更新 更多