XmlSerializer десериализация массива / список нескольких объектов в корне - PullRequest
0 голосов
/ 22 декабря 2009

Я пытаюсь десериализовать следующий вывод XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<Foo>
   <Val>Data1</Val>
</Foo>
<Foo>
   <Val>Data2</Val>
</Foo>

(Это вывод с аппаратного устройства, и его нельзя изменить)

У меня есть тип XML, определенный как:

    [XmlType(AnonymousType=true, Namespace="")]
    public class Foo
    {
        public string Val { get; set; }
    }

Я попытался десериализовать этот массив, создав сериализатор вроде:

  var s = new XmlSerializer(typeof(Foo[]));
  //or
  var s = new XmlSerializer(typeof(List<Foo>);

Но каждый вызов s.Deserialize () вызывает исключение InvalidOperaitonException:

 System.InvalidOperationException: <Foo xmlns=''> was not expected.

Примечание

 var s = new XmlSerializer(typeof(Foo));
 // Only deseralizes the first Foo (Data1).

Спасибо за вашу помощь.

Ответы [ 6 ]

8 голосов
/ 22 декабря 2009

Я думаю, что проблема связана с предоставленным вами XML.

Тестовое приложение говорит

List<Foo> list = new List<Foo> {new Foo {Val = "Data1"}, new Foo {Val = "Data2"}};
var s = new XmlSerializer(typeof(List<Foo>));
StringBuilder sb = new StringBuilder();
XmlWriter wr = XmlWriter.Create(sb);
s.Serialize(wr, list);

string ss = sb.ToString();

var s2 = new XmlSerializer(typeof(List<Foo>));
StringReader sr = new StringReader(ss);
List<Foo> returnList = (List<Foo>)s2.Deserialize(sr);

И XML должен быть

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfFoo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Foo>
        <Val>Data1</Val>
    </Foo>
    <Foo>
        <Val>Data2</Val>
    </Foo>
</ArrayOfFoo>

Если вы можете удалить начальную линию

<?xml version="1.0" encoding="ISO-8859-1"?>

И минимизировать строку в

string s = "<ArrayOfFoo><Foo>   <Val>Data1</Val></Foo><Foo>   <Val>Data2</Val></Foo></ArrayOfFoo>";
var s2 = new XmlSerializer(typeof(List<Foo>));
StringReader sr = new StringReader(s);
List<Foo> list = (List<Foo>)s2.Deserialize(sr);

Это может сработать.

7 голосов
/ 22 декабря 2009

Это не действительно Xml. Для его правильной работы должен быть основной корневой элемент.

3 голосов
/ 22 декабря 2009

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

String ss; 
// lets assume this holds your xml data in string.
ss.append("</ArrayOfFoo>");
ss.replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", "<?xml version=\"1.0\" encoding=\"utf-16\"?> <ArrayOfFoo>")

var s2 = new XmlSerializer(typeof(List<Foo>));
StringReader sr = new StringReader(ss);
List<Foo> returnList = (List<Foo>)s2.Deserialize(sr); 

Теперь это вернет вам правильный список.

1 голос
/ 22 декабря 2009

Технически, у вас есть не a правильно сформированный XML-документ (который имеет ровно один корневой элемент), а скорее правильно сформированный внешний проанализированный объект (который может содержать любое количество элементов, не содержащихся в других элементах, а также текст, не содержащийся ни в каких элементах). Следовательно, он должен анализировать, если ваш синтаксический анализатор XML имеет точку входа для анализа EPE, а не документов. Вы также можете создать тупиковый документ, который включает в себя ссылку на ваш EPE и анализирует этот документ.

1 голос
/ 22 декабря 2009

Как говорят другие авторы, этот XML, который производит аппаратное устройство, несовместим с тем, как .NET сериализует / десериализует объект. Допустимый XML, а для .NET требуется допустимый XML, есть корневой элемент.

Я предлагаю:

  • либо вы модифицируете полученный XML-файл так, чтобы он соответствовал тому, как astander представляет его фрагмент кода xml.
  • или вы пишете простой xml-анализатор для вашего файла, который десериализует файл так, как вам нужно

br, Марсель

0 голосов
/ 22 декабря 2009

Xstream для .Net может быть полезным API

...