2010-02-19 34 views
19

Tôi thấy có hành vi lạ khi tôi cố gắng phân tích cú pháp XML bằng cách sử dụng lớp LINQ XmlReader. Trường hợp kiểm tra bên dưới: có vẻ như tôi có sử dụng (XElement)XNode.ReadFrom(xmlReader) hoặc một trong các phương pháp Read() trên XmlReader hay không, nó bỏ qua phần tử bar thứ hai trong XML đầu vào. Nếu bất kỳ khoảng trắng nào được thêm vào giữa các số </bar><bar> thì nó sẽ phân tích cú pháp phần tử bar thứ hai chính xác.Tại sao XmlReader bỏ qua mọi phần tử khác nếu không có dấu cách khoảng trắng?

Có ai có ý tưởng về lý do khiến luồng đầu vào bị làm rối tung và cách khắc phục sự cố này không?

[Test] 
    [Explicit] 
    public void ShouldParseCorrectNumberOfElements() 
    { 
     var xml = @"<foo><bar>wtf</bar><bar>wtf2</bar></foo>"; 
     XmlReader xmlReader = XmlReader.Create(new MemoryStream(Encoding.UTF8.GetBytes(xml))); 

     int count = 0; 
     xmlReader.MoveToContent(); 
     while (xmlReader.Read()) 
     { 
      if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "bar") 
      { 
       var element = xmlReader.ReadOuterXml(); 
       Console.WriteLine("just got an " + element); 
       count++; 
      } 
     } 
     Assert.AreEqual(2, count); 
    } 
+0

Vòng lặp có thể được tối ưu hóa đáng kể bằng cách sử dụng 'ReadToFollowing ("bar") 'thay vì' Read() '(chỉ hoạt động với Jon của câu trả lời quá). –

+0

Tôi có một trường hợp tương tự và tôi đang sử dụng 'ReadToFollowing' với' While' và 'ReadOuterXml' bên trong vòng lặp while. Nếu tài liệu được định dạng bằng dòng mới, nó hoạt động đúng. Khi tôi có một tài liệu dòng đơn nó bỏ qua tất cả các nút sau đây. –

Trả lời

30

Bạn đang gọi ReadOuterXml, sẽ tiêu thụ phần tử và đặt "con trỏ" ngay trước phần tử tiếp theo. Sau đó, bạn gọi lại số Read, di chuyển con trỏ trên (ví dụ: đến nút văn bản trong phần tử).

Dưới đây là một thay thế cho vòng lặp của bạn:

while (!xmlReader.EOF) 
{ 
    Console.WriteLine(xmlReader.NodeType); 
    if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "bar") 
    { 
     var element = xmlReader.ReadOuterXml(); 
     Console.WriteLine("just got an " + element); 
     count++;     
    } 
    else 
    { 
     xmlReader.Read(); 
    } 
} 
+0

Ồ, cảm giác "tắt một" ... Cảm ơn một lần nữa! –

6

Bạn có thể bỏ qua một dòng bằng cách gọi hàm Read() trong điều kiện vòng lặp while và sau đó hàm ReadOuterXml() trong vòng lặp không?

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