2013-03-28 3 views
1

Первый раза с помощью LINQ к XML, восхождение кривого обучения ...LINQ к XML: разбор простому ввода XML

Ищу для плавного способа, как извлечь и преобразовать данные из файла XML, как мало if-else и, боже, запретите, заявления о попытках. Я действительно ненавижу весь этот длинный код, чтобы получить только одно значение из документа.

Сказав это, я ищу отказоустойчивое решение, которое не сработает, если структура XML-документа неожиданно изменилась. В таком случае я ожидаю, что нулевое значение будет восстановлено, поэтому я могу проверить его позже в коде.

Вот мой XML документ:

<?xml version="1.0" encoding="utf-8"?> 
<Entry> 
    <IntField>11</IntField> 
    <StringField>String data</StringField> 
    <DateTimeField>28/03/2013 18:10:02</DateTimeField> 
</Entry> 

Я ищу кода, где я получить одно значение для каждой строки кода, а именно:

myXMLdoc = XDocument.Load("sourceFile.xml"); 
int? myIntField = (smart linq query that retrieves&converts the value, with fallback of null); 
string? myStringField = (smart linq query etc.); 
DateTime? myDateTimeField = (smart linq query etc.); 
if (myIntField == null) 
{ 
    // Complain that structure of the XML doc is bad 
} 

Возможно, мои ожидания, что LINQ может сделать это наивные , но, хорошо, написав комки и куски выражений XPath и операторы if-else для тривиальной симпатичной обработки XML, я получил некоторую горечь об этом. Поэтому я обращаюсь к LINQ с большими надеждами.

ответ

2

Хотя LINQ2XML сам по себе не обладает необходимой «магией», он предлагает достаточно «подкрепления» для того, чтобы вы сами создали код. Вот пример, который показывает вам, как читать int? из элемента на произвольной глубине (в предположении, что путь является уникальным, конечно):

public static class LinqExt { 
    public static int? ReadInt(this XElement e, string path, int? fallback = null) { 
     foreach (var name in path.Split('/')) { 
      e = e.Element(name); 
      if (e == null) { 
       return fallback; 
      } 
     } 
     int val; 
     return int.TryParse(e.Value, out val) ? val : fallback; 
    } 
} 

Вы можете использовать этот метод расширения следующим образом:

var myXMLdoc = XDocument.Load("sourceFile.xml"); 
var intVal = myXMLdoc.Root.ReadInt("IntField"); 

метод будет работать даже с некоторым вложенности, например, если ваш документ выглядит следующим образом

<?xml version="1.0" encoding="utf-8"?> 
<Entry> 
    <Nested1> 
     <Nested2> 
      <IntField>11</IntField> 
     </Nested2> 
    </Nested1> 
</Entry> 

вы получите значение, как это:

var intVal = myXMLdoc.Root.ReadInt("Nested1/Nested2/IntField"); 
+0

Через метод расширения, очень умный, спасибо. – Passiday