2013-03-14 25 views
6

Tôi đang cố đọc các giá trị phần tử từ một tài liệu XML đơn giản và liên kết chúng với một đối tượng. bằng tài liệu XML của tôi. Tôi đã xác nhận nó và có thể khẳng định không có vấn đề với tài liệu tuy nhiên bản thân mở rộng các kết quả trên dòng:Phát hành de-serializing XML thành Object - Có lỗi trong tài liệu XML (0, 0)

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

Hiện "Có một lỗi trong tài liệu XML (0, 0)"

Ngoại lệ bên trong đọc <RewriteRules xmlns=''> was not expected.

Tôi không chắc mình đang làm gì sai ở đây?

XML của tôi là dưới đây:

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

Mã tải các tập tin XML và cố gắng để de-serialize nó: -

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

My Url đối tượng lớp: -

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

Có ai có thể nhìn thấy những gì tôi đang làm sai ở đây không?

Cảm ơn

+0

Dig vào ngoại lệ cơ sở gây ra đó. – leppie

Trả lời

4

Tôi không quá quen thuộc với báo cáo kết quả from select, nhưng có vẻ như bạn chỉ cần vượt qua trong xml đó là toàn bộ XDocument, thay vì XElementRewriteRule của bạn. Đó là lý do tại sao bạn nhận được thông báo lỗi rằng RewriteRules không xác định - XmlSerializer mong đợi một RewriteRule duy nhất.

Tôi quản lý để viết lại mã của bạn bằng cách sử dụng LINQ thay vào đó (nhưng nếu bạn biết cách lấy phần tử đơn từ câu lệnh from select, điều đó sẽ hoạt động tốt như nhau).

này sẽ cho bạn kết quả chính xác - rrXElement được trả về từ 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

có lẽ nó là 'xDoc'? vì vậy 'select xmlSerializer.Deserialize (xDoc.CreateReader())'? – Default

+0

Có phần tử sẽ là 'xDoc', không nghĩ đến việc thử CreateReader trên chính phần tử đó, tôi sẽ thử nghiệm này một cách nhanh chóng – DGibbs

+0

Đúng, đó là tất cả những gì tôi đã bỏ lỡ. Đã thay đổi 'xml.CreateReader()' thành 'xDoc.CreateReader()'. Hoạt động hoàn hảo ngay bây giờ, cảm ơn! – DGibbs

3

EDIT: Tên của lớp Url của bạn không phù hợp. Bạn cần phải đổi tên nó thành "RewriteRule" hoặc định nghĩa nó theo cách này:

[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

Xin chào @Patrick, tôi đã thử thêm lớp 'RewriteRules' của bạn và sửa đổi phương thức của tôi nhưng tôi vẫn nhận được lỗi tương tự. Thật kỳ lạ, nếu tôi sửa thuộc tính 'Url' của lớp' XmlRoot' thành 'RewriteRules' thay vì' RewriteRule' thì deserializer không ném lỗi nhưng các giá trị liên kết với đối tượng của tôi là tất cả 'null' vì vậy vẫn còn một thứ rất lạ xảy ra – DGibbs

+0

Điều này thật kỳ lạ. Tôi đã thiết lập một thử nghiệm và nó đã làm việc (tôi cũng sử dụng mã của bạn ở trên với cuộc gọi deserialze). Trình chỉnh sửa của bạn có cung cấp các tệp xml đúng không? Tôi sử dụng notepad ++. Không phải là tệp xml là vấn đề. – Patrick

+0

Tôi đã tạo tài liệu xml qua VS và sử dụng w3c [validator] (http://validator.w3.org) để kiểm tra nó – DGibbs

1

cách tiếp cận của tôi là được sử dụng nhiều hơn, khi bạn deserialize nó trực tiếp đến một thể hiện của một lớp.

Nếu bạn muốn sử dụng XDocument, bạn có thể viết nó như thế này. Tôi không sử dụng XDocument trong mã của tôi. Vì tôi cần phải deserialize các gói xml đầy đủ tôi làm điều đó trực tiếp với deserialize của nút gốc. Vì vậy, tôi đã đề xuất cho nút gốc đến đúng nơi trong bài trước.

Với XDocument bạn có thể truy cập trực tiếp các nhánh con. Dưới đây là mã làm việc cho mục đích của bạn, nhưng có thể có những người khác có thể giúp bạn thiết lập mã này lên tao nhã hơn:

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

Điều này làm việc cảm ơn, nhầm lẫn về lý do tại sao sử dụng phiên bản loại ẩn danh hoạt động trong khi trước khi trả về giá trị null cho các thuộc tính. Bạn có thể giải thích? Thay vì lặp qua các url, tôi đã tạo một hàm tạo mới trong lớp 'UrlCollection' của mình có bộ sưu tập động và tạo một url mới từ đó, ví dụ: 'công khai UrlCollection (IEnumerable url) {this.Items.Clear(); foreach (mục động trong url) {Url url = new Url (item.From, item.To, item.StatusCode); this.Add (url); }} '. P.s bạn luôn có thể chỉnh sửa câu trả lời hiện có;) – DGibbs

+0

Xin chào, có vẻ như bộ nối tiếp không thích tên của Url lớp học của bạn. Bạn cần đổi tên nó thành "RewriteRule" hoặc thêm dòng: [Serializable] [System.Xml.Serialization.XmlRoot ("RewriteRule")] public class Url – Patrick

Các vấn đề liên quan