2016-08-05 3 views
0

Попытка десериализации списка. Im получаю следующее сообщение об ошибке:XmlSerializer Deserializing List Без пространства имен

System.InvalidOperationException: There is an error in XML document (1, 2). ---> System.InvalidOperationException: was not expected.

пила другие quesitons как: {"<user xmlns=''> was not expected.} Deserializing Twitter XML, но это не решает мою проблему либо.

Это Xml Sample

<authorizations> 
    <id>111</id> 
    <name>Name 1</name> 
    <Lists> 
    <List> 
     <id>1</id> 
     <id>2</id> 
    </List> 
    </Lists> 
</authorizations> 
<authorizations> 
    <id>222</id> 
    <name>Name 2</name> 
    <List /> 
</authorizations> 
<authorizations> 
    <id>333</id> 
    <name>Name 3</name> 
    <List /> 
</authorizations> 

Класс создаются следующим образом:

public class Authorization 
    { 
     [XmlElement("id")] 
     public string Id{ get; set; } 
     [XmlElement("name")] 
     public string Name{ get; set; } 
     [XmlArray("Lists")] 
     [XmlArrayItem("List")] 
     public List[] Items{ get; set; } 
    } 

    public class List 
    { 
     [XmlElement("id")] 
     public string Id{ get; set; } 
    } 

    public class AuthorizationList 
    { 
     [XmlArray("authorizations")] 
     public Authorization Authorizations{ get; set; } 
    } 

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

десериализации Пример кода:

public static T FromXml<T>(string xmlString) 
    { 
     T obj = default(T); 

     if (!string.IsNullOrWhiteSpace(xmlString)) 
     { 
      using (var stringReader = new StringReader(xmlString)) 
      { 
       var xmlSerializer = new XmlSerializer(typeof(T)); 

       obj = (T)xmlSerializer.Deserialize(stringReader); 
      } 
     } 

     return obj; 
    } 
+0

Это не * действительный * (ожидаемый 'XmlSerializer') xml. Действительный начинается с ''. Вы можете попробовать добавить эту строку до вызова 'Deserialize()'. Другое дело - отсутствие контейнера (обозначенного символом 'XmlRootAttribute') для элементов массива, см., Например, [Это] (http://stackoverflow.com/q/126155/1997232). – Sinatr

+0

'XmlSerializer' может обрабатывать XML, в котором отсутствует декларация XML. Однако XML должен иметь один и только один [корневой элемент] (https://en.wikipedia.org/wiki/Root_element). Этот XML имеет несколько корневых элементов, поэтому совсем не XML. – dbc

+0

Попробуйте добавить корневой элемент и сообщите об этом.Спасибо за быстрые ответы – RSmart

ответ

0

Это все основывается на предположении, что у вас есть минимальный контроль над XML и не могут позволить себе роскошь изменения, что слишком много. Как отмечали другие, он плохо сформирован. Вот один из способов заставить сериализацию работать с минимальными изменениями в вашем XML и типах. Сначала избавьтесь от своего типа AuthorizationList и назначьте атрибут XmlType вашему типу авторизации (этот шаг служит для простого дублирования имени в соответствии с вашим xml-файлом).

[XmlType("authorizations")] 
public class Authorization { ... } 

public class List { ... } 

Оберните XML в следующем корневом элементе ...

<ArrayOfAuthorizations> 
... 
</ArrayOfAuthorizations> 

XML-теперь представляет список "разрешений", так десериализовать только это ...

List<Authorization> l = FromXml<List<Authorization>>(xml); 

Другое решение ...

Изменить Authorizations член должен быть типа Authorization[] (тип массива, а не сингулярный) и иметь атрибут XmlElement (не XmlArray). Примените атрибут XmlType к Authorization (как и в случае с вышеупомянутым решением, это должно соответствовать xml, поскольку оно имеет множественное имя для каждого элемента массива).

[XmlType("authorizations")] 
public class Authorization 
{ 
    [XmlElement("id")] 
    public string Id { get; set; } 
    [XmlElement("name")] 
    public string Name { get; set; } 
    [XmlArray("Lists")] 
    [XmlArrayItem("List")] 
    public List[] Items { get; set; } 
} 

public class List 
{ 
    [XmlElement("id")] 
    public string Id { get; set; } 
} 

public class AuthorizationList 
{ 
    [XmlElement("authorizations")] 
    public Authorization[] Authorizations { get; set; } 
} 

Тогда десериализации экземпляра вашего AuthorizationList типа, а тот List<T> как и в предыдущем решении.

AuthorizationList l = FromXml<AuthorizationList>(xml); 

Обратите внимание, что корневой элемент XML также должен соответствовать этому типу.

<AuthorizationList> 
<authorizations> 
    <id>111</id> 
    <name>Name 1</name> 
    <Lists> 
    <List> 
     <id>1</id> 
     <id>2</id> 
    </List> 
    </Lists> 
</authorizations> 
<authorizations> 
    <id>222</id> 
    <name>Name 2</name> 
    <List /> 
</authorizations> 
<authorizations> 
    <id>333</id> 
    <name>Name 3</name> 
    <List /> 
</authorizations> 
</AuthorizationList> 
+0

Дает мне ту же ошибку и не понимает, зачем обертывать корневым элементом, если он не используется в коде. – RSmart

+0

Я просто показывал один подход, который дает понять, что вам не нужно определять свой тип «AuthorizationList», чтобы полностью удовлетворить сериализатор. Корневой элемент 'ArrayOf ...' является стандартным соглашением, которое 'XmlSerializer' будет ожидать там, где' ... '- это имя параметра общего типа. Опять же, предполагается, что вы захотите упростить и просто использовать «Список » вместо того, чтобы определять «AuthorizationList» только для удовлетворения требования к корневому элементу. Я отредактирую и добавлю альтернативный подход, который сохранит ваш 'AuthorizationList', поскольку, возможно, вам это нужно? – blins

+0

См. Мое редактирование, в котором показана альтернатива, которая хранит ваш тип «AuthorizationList» и делает его корнем в xml. – blins

Смежные вопросы