2013-03-14 1 views
6

Я пытаюсь прочитать значения элементов из простого документа XML и привязать их к объекту, однако я столкнулся с проблемами с моим XML-документом. Я подтверждено его и может подтвердить, нет никаких проблем с документом сам, однако расширяющейся результаты на линии:Проблема де-сериализации XML для объекта - В XML-документе есть ошибка (0, 0)

var nodes = from xDoc in xml.Descendants("RewriteRule") 
       select xmlSerializer.Deserialize(xml.CreateReader()) as Url; 

Показать «Существует ошибка в документе XML (0, 0)»

Внутренние исключения читаются <RewriteRules xmlns=''> was not expected.

Я не уверен, что я здесь делаю неправильно?

Мой XML ниже:

<?xml version="1.0" encoding="utf-8" ?> 
<RewriteRules> 
    <RewriteRule> 
     <From>fromurl</From> 
     <To>tourl</To> 
     <Type>301</Type> 
    </RewriteRule> 
</RewriteRules> 

код, который загружает файл XML и пытается десериализации его: -

public static UrlCollection GetRewriteXML(string fileName) 
{ 
    XDocument xml = XDocument.Load(HttpContext.Current.Server.MapPath(fileName)); 
    var xmlSerializer = new XmlSerializer(typeof(Url)); 

    var nodes = from xDoc in xml.Descendants("RewriteRule") 
       select xmlSerializer.Deserialize(xml.CreateReader()) as Url; 

    return nodes as UrlCollection; 
} 

Мой Url объект класса: -

[Serializable] 
[XmlRoot("RewriteRule")] 
public class Url 
{ 
    [XmlElement("From")] 
    public string From { get; set; } 
    [XmlElement("To")] 
    public string To { get; set; } 
    [XmlElement("Type")] 
    public string StatusCode { get; set; } 

    public Url() 
    { 
    } 

    public Url(Url url) 
    { 
     url.From = this.From; 
     url.To = this.To; 
     url.StatusCode = this.StatusCode; 
    } 
} 

Может ли кто-нибудь увидеть, что я делаю неправильно здесь?

Благодаря

+0

Dig в базу исключением того, что причиной того, что. – leppie

ответ

4

Я не слишком хорошо знаком с from select заявления, но мне кажется, вы просто передать в xml который является целым XDocument, а не XElement, что является вашим RewriteRule. Вот почему вы получаете сообщение об ошибке, что RewriteRules неизвестно - XmlSerializer ожидает один RewriteRule.

Вместо этого мне удалось переписать код, используя LINQ (но если вы знаете, как получить один элемент из инструкции from select, это должно работать одинаково хорошо).

Это должно дать вам правильный результат - rr является XElement, который возвращается из Descendants:

public static IEnumerable<Url> GetRewriteXML() 
{ 
    XDocument xml = XDocument.Load(HttpContext.Current.Server.MapPath(fileName)); 

    var xmlSerializer = new XmlSerializer(typeof(Url)); 

    var nodes = xml.Descendants("RewriteRule") 
       .Select(rr => xmlSerializer.Deserialize(rr.CreateReader()) as Url); 

    return nodes; 
} 
+0

может быть, это 'xDoc'? поэтому 'select xmlSerializer.Deserialize (xDoc.CreateReader())'? – Default

+0

Да, элемент будет 'xDoc', не думал попробовать CreateReader на самом элементе, я дам это быстрый тест – DGibbs

+0

Да, это было все, что мне не хватало. Изменен 'xml.CreateReader()' на 'xDoc.CreateReader()'. Отлично работает сейчас, спасибо! – DGibbs

3

EDIT: имя вашего класса URL не соответствует. Вы должны переименовать его в «RewriteRule» или определить его таким образом:

[Serializable] 
[System.Xml.Serialization.XmlRoot("RewriteRule")] 
public class Url 
{ 
    [XmlElement("From")] 
    public string From { get; set; } 
    [XmlElement("To")] 
    public string To { get; set; } 
    [XmlElement("Type")] 
    public string StatusCode { get; set; } 

    public Url() 
    { 
    } 
    public Url(Url url) 
    { 
     url.From = this.From; 
     url.To = this.To; 
     url.StatusCode = this.StatusCode; 
    } 
} 
+0

Привет @Patrick, я попробовал добавить свой класс «RewriteRules» и модифицировать мой метод, но все равно получаю ту же ошибку. Любопытно, что если я изменю атрибут 'XmlRoot' класса' Url' класса 'RewriteRules' вместо' RewriteRule', десериализатор не выдаст ошибку, но значения, привязанные к моему объекту, будут «null», поэтому все еще есть что-то очень странно происходит – DGibbs

+0

Это странно. Я установил тест, и он сработал (я также использовал ваш код выше с вызовом deserialze). Предоставляет ли ваш редактор правильные файлы xml? Я использую блокнот ++. Не проблема в том, что xml-файл является проблемой. – Patrick

+0

Я создал xml-документ через VS и использовал w3c [validator] (http://validator.w3.org), чтобы проверить его. – DGibbs

1

мой подход больше используется, когда вы десериализации его непосредственно к экземпляру класса.

Если вы хотите использовать XDocument, вы можете просто написать его вот так. Я не использую XDocument в своем коде. Поскольку мне нужно десериализовать полные пакеты xml, я делаю это непосредственно с десериализацией корневого узла. Поэтому я предложил корневому узлу в нужном месте в предыдущем сообщении.

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

public static UrlCollection GetRewriteXML(string fileName) 
    { 
     XDocument xml = XDocument.Load(HttpContext.Current.Server.MapPath(fileName)); 
     var urls = from s in xml.Descendants("RewriteRule") 
        select new 
        { 
         From = (string)s.Element("From").Value, 
         To = (string)s.Element("To").Value, 
         StatusCode = (string)s.Element("Type").Value 
        }; 
     UrlCollection nodes = new UrlCollection(); 
     foreach (var url in urls) 
     { 
      nodes.Add(new Url(url.From, url.To, url.StatusCode)); 
     } 
     return nodes; 
    } 

[Serializable] 
public class Url 
{ 
    [XmlElement("From")] 
    public string From { get; set; } 
    [XmlElement("To")] 
    public string To { get; set; } 
    [XmlElement("Type")] 
    public string StatusCode { get; set; } 

    public Url() 
    { 
    } 

    public Url(string From, string To, string StatusCode) 
    { 
     this.From = From; 
     this.To = To; 
     this.StatusCode = StatusCode; 
    } 

    public Url(Url url) 
    { 
     url.From = this.From; 
     url.To = this.To; 
     url.StatusCode = this.StatusCode; 
    } 
} 
+0

Это сработало, в замешательстве, почему работа с анонимным типом работала, тогда как до того, как он возвращал нулевые значения для свойств. Вы можете объяснить? Вместо итерации по URL-адресам я создал новый конструктор в классе 'UrlCollection', который принимает динамическую коллекцию и создал новый URL-адрес из этого, например. 'public UrlCollection (IEnumerable URL) {this.Items.Clear(); foreach (динамический элемент в URL-адресах) {Url url = новый Url (item.From, item.To, item.StatusCode); this.Add (URL); }} '. P.s вы всегда можете отредактировать существующий ответ;) – DGibbs

+0

Привет, кажется, что сериализатору не нравится имя вашего класса Url. Вам нужно переименовать его в «RewriteRule» или добавить строку: [Serializable] [System.Xml.Serialization.XmlRoot («RewriteRule»)] public class Url – Patrick

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