2013-03-14 5 views
6

Ich versuche, Elementwerte aus einem einfachen XML-Dokument einzulesen und diese an ein Objekt zu binden, aber ich stoße auf Probleme mit meinem XML-Dokument. Ich habe es überprüft und kann bestätigen, gibt es keine Probleme mit dem Dokument selbst jedoch die Ergebnisse auf der Linie erweitert:Problem beim Deserialisieren von XML zum Objekt - Es gibt einen Fehler im XML-Dokument (0, 0)

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

anzeigen „Es ist ein Fehler in XML-Dokument (0, 0)“

Die innere Ausnahmen liest <RewriteRules xmlns=''> was not expected.

Ich bin mir nicht sicher, was ich hier falsch mache?

Meine XML ist unter:

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

Der Code, der die XML-Datei lädt und versucht, es zu zu deserialisieren: -

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

Meine URL Objektklasse: -

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

Kann jemand sehen, was ich hier falsch mache?

Dank

+0

Dig in die Basis Ausnahme, die das verursacht. – leppie

Antwort

4

Ich bin nicht allzu vertraut mit der from select Aussage, aber es scheint, dass Sie passieren nur in xml Das ist das ganze XDocument, anstelle der XElement das ist Ihr RewriteRule. Aus diesem Grund erhalten Sie die Fehlermeldung, dass RewriteRules unbekannt ist - die XmlSerializer erwartet eine einzige RewriteRule.

Ich habe es geschafft, Ihren Code mit LINQ stattdessen umschreiben (aber wenn Sie wissen, wie Sie das einzelne Element aus der from select Anweisung erhalten, sollte das genauso gut funktionieren).

Dies sollten Sie das richtige Ergebnis geben - rr ist die XElement, die von Descendants zurückgegeben:

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

vielleicht ist es "xDoc"? Wählen Sie also xmlSerializer.Deserialize (xDoc.CreateReader()) '? – Default

+0

Ja, das Element wäre 'xDoc', dachte nicht, CreateReader auf dem Element selbst auszuprobieren, ich gebe dies einen schnellen Test – DGibbs

+0

Ja, das war alles, was ich vermisste. 'Xml.CreateReader()' in 'xDoc.CreateReader()' geändert. Funktioniert jetzt perfekt, danke! – DGibbs

3

EDIT: Der Name Ihrer URL-Klasse nicht übereinstimmt. Sie müssen es „RewriteRule“ umbenennen oder es auf diese Weise definieren:

[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

Hallo @Patrick, ich habe versucht, Ihre 'RewriteRules' Klasse hinzuzufügen und meine Methode zu ändern, aber ich bekomme immer noch den gleichen Fehler. Seltsamerweise, wenn ich mein 'Url'-Klasse' XmlRoot'-Attribut zu 'RewriteRules' anstelle von 'RewriteRule' ändere, wirft der Deserializer keinen Fehler, aber die an mein Objekt gebundenen Werte sind alle' null', also ist da noch etwas sehr komisch geht weiter – DGibbs

+0

Das ist seltsam. Ich habe einen Test eingerichtet und es hat funktioniert (ich habe auch Ihren Code oben mit deserialze Anruf verwendet). Bietet Ihr Editor korrekte XML-Dateien? Ich benutze Notizblock ++. Nicht, dass die XML-Datei das Problem ist. – Patrick

+0

Ich erstellte das XML-Dokument via VS und benutzte das W3C [Validator] (http://validator.w3.org), um es zu überprüfen – DGibbs

1

mein Ansatz mehr genutzt wird, wenn Sie es direkt an eine Instanz einer Klasse deserialisieren.

Wenn Sie XDocument verwenden möchten, können Sie es einfach so schreiben. Ich verwende XDocument nicht in meinem Code. Da ich die vollständigen XML-Pakete deserialisieren muss, mache ich das direkt mit der Deserialisierung des Wurzelknotens. Daher habe ich dem Wurzelknoten im vorherigen Beitrag den richtigen Platz vorgeschlagen.

Mit XDocument können Sie direkt auf Unterabschnitte zugreifen. Hier arbeitet Code für Ihren Zweck, aber es könnte noch andere geben, die helfen können Sie diesen Code einrichten elegantere:

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

Dies funktionierte dank, warum die Verwendung der anonymen Version funktionierte, während vorher NULL-Werte zurückgegeben wurden für die Eigenschaften. Können Sie erklären? Anstatt über die URLs zu iterieren, habe ich einen neuen Konstruktor in meiner 'UrlCollection'-Klasse erstellt, der eine dynamische Sammlung verwendet und eine neue URL erstellt hat, z. 'public UrlCollection (IEnumerable urls) {this.Items.Clear(); foreach (dynamisches Element in URLs) {Url url = neues Url (item.From, item.To, item.StatusCode); this.Add (URL); }} '. P.S Sie können immer eine vorhandene Antwort bearbeiten;) – DGibbs

+0

Hallo, es scheint, dass der Serializer den Namen Ihrer Klasse Url nicht mag. Sie müssen es umbenennen in "RewriteRule" oder fügen Sie die Zeile hinzu: [Serializable] [System.Xml.Serialization.XmlRoot ("RewriteRule")] öffentliche Klasse Url – Patrick

Verwandte Themen