2012-10-24 34 views
2

我想解析一些xml,我在使用.net 3.5中的Linq时会出现错误,我需要从xml中获取数据并将数据插入变量,我一直使用XmlDocument解析XML,任何实例或协助不胜感激用Linq解析格式不正确的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”值可以包含特殊字符,如! ,%,^ &等,我知道有时可能会导致与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"))); 
     } 
+0

您是否包含XML示例?它没有出现(至少不是我)。 –

+3

LINQ to XML假定有效的XML - 它不能处理格式不正确的XML。 – Oded

+0

您发布的XML格式良好。有什么问题? – Oded

回答

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"]); 
+1

谢谢LB这段代码完美无缺! – Brad

1

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

ETA:好的,现在我正在重做这个,以便更好地了解您的XML。

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

您还需要查看属性集合,因为这就是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)); 
} 
+0

安,我想同样的事情,并试图改变“场”,并没有结果,我也试过“数据”,“行”,“名称”和“centovacast”由于某种原因没有产生任何结果.. – Brad

+0

我'我添加了一些更多的代码 - 这对我来说可能是错误的,因为我假定你有一个父元素,而你可能有几个。我会解决它。 ETA:好的,固定的。请记住,尽管如此,我从内存中完成了这些操作,并且可能会将方法名称混淆。 –

+0

ann,这段代码看起来不错,我非常感谢你的帮助,但是qe.Attributes [“”]。当我尝试编译它时,Value会抛出一个错误 - 无法对[]方法组的表达式应用索引' – Brad

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)); 
}