使用Linq解析格式错误的XML

时间:2012-10-24 18:43:04

标签: c# .net xml winforms linq

我正在尝试使用Linq在.net 3.5中解析一些我可能会出错的xml,我需要从xml中获取数据并将数据插入变量中,我一直在使用XmlDocument来解析xml,非常感谢任何示例或帮助

XML -

<?xml version="1.0" encoding="UTF-8"?>
<centovacast version="2.2.4" host="my.domain.com">
<response type="success">
<message>Complete</message>
<data><row>
<field name="mount">/stream</field>
<field name="listenercount">0</field>
<field name="genre">Unspecified</field>
<field name="url">http://</field>
<field name="title"></field>
<field name="currentsong">Placebo - One Of A Kind</field>
<field name="bitrate">128</field>
<field name="sourceconnected">1</field>
<field name="serverstate">1</field>
<field name="sourcestate">1</field>
<field name="reseller">0</field>
<field name="ipaddress"></field>
<field name="port">13282</field>
<field name="proxy">0</field>
<field name="servertype">ShoutCast</field>
<field name="sourcetype">icescc</field>
</row><row><field></field></row></data></response></centovacast>

另一个问题是,有时“currentsong”值可能包含特殊字符,例如! ,%,^&amp;等我知道有时会导致xml出现问题。

- 我正试图用来解析XML的代码

        XElement xml = XElement.Parse(data);

        var query = from p in xml.Elements("name")
                    select p;

        foreach (var record in query)
        {
            MessageBox.Show(String.Format("Info: {0} {1}",
                                                record.Element("url"),
                                                record.Element("title")));
        }

3 个答案:

答案 0 :(得分:1)

你的LINQ错了。您正在寻找名为name的元素。你没有。您有名为field的元素。

ETA:好的,我正在重做这个,因为我可以更好地查看你的XML。

  var query = from r in xml.Elements("row") 
                select r; 

您还需要查看Attributes集合,因为name就是:属性。以下内容来自内存,但它看起来像这样:

foreach(XElement row in query)
{
    var urlElement = row.Elements("field").Single(qe=>qe.HasAttributes && qe.Attribute("name").Value == "url");
    var titleElement = row.Elements("field").Single(qe => qe.HasAttributes && qe.Attribute("name").Value == "title");
    MessageBox.Show(String.Format("Info: {0} {1}", urlElement.Value, titleElement.Value));
}

答案 1 :(得分:0)

下面的Linq2Xml代码适用于您的xml。

var xDoc = XDocument.Parse(xml); //XDocument.Load(filename)

var dict = xDoc.Descendants("field")
               .Where(e=>e.HasAttributes)
               .ToDictionary(e => e.Attribute("name").Value, e => e.Value);

Console.WriteLine(dict["currentsong"]);

答案 2 :(得分:0)

以下代码将以您希望的方式解析XML。请注意,如果XElement中包含任何特殊字符,则可能会遇到XElement抛出异常的问题。在尝试解析之前,您可能希望预先处理字符串以正确地转义这些字符。另请注意,它不喜欢带有空字段元素的第二行元素。如果你希望从你的源代码获得类似的东西,你必须编写一些错误处理来找到它或捕获异常并转储整行。

提供的XML形式不是很糟糕,但它很奇怪 - 每个字段的名称应该是元素的名称,而不是它的属性。这使解析它有点棘手。这使用后代跳过其他元素并直接获取文件中的所有行元素。然后使用Linq First方法查找具有所需属性值的元素,并从中获取元素值。

var query = from p in xml.Descendants("row")
                    select p;

foreach (var record in query)
{
    MessageBox.Show(String.Format("Info: {0} {1}",
        record.Elements().First(e => e.Attribute("name").Value.Equals("url")).Value,
        record.Elements().First(e => e.Attribute("name").Value.Equals("title")).Value));
}