2010-06-01 18 views
7

hey guys, tôi đã có kịch bản này:Làm thế nào để đọc từ một XmlReader, không nhúc nhích nó chuyển tiếp

while (reader.Read()) 
{ 
    if (reader.NodeType == XmlNodeType.Element && reader.Name == itemElementName) 
    { 
     XElement item = null; 
     try 
     { 
      item = XElement.ReadFrom(reader) as XElement; 
     } 
     catch (XmlException ex) 
     { 
      //log line number and stuff from XmlException class 
     } 
    } 
} 

trong vòng lặp trên tôi chuyển một nút nào đó (itemElementName) vào một XElement.

Một số nút sẽ là XML tốt và sẽ đi vào XElement, tuy nhiên, một số sẽ không.

Trong CATCH, tôi muốn không chỉ bắt các công cụ XmlException tiêu chuẩn ... Tôi cũng muốn bắt một trích xuất của Xml hiện tại và một chuỗi.

Tuy nhiên, nếu tôi thực hiện bất kỳ thao tác ĐỌC nào trên nút trước khi tôi chuyển nó vào XElement, nó sẽ di chuyển đầu đọc về phía trước.

Làm cách nào để có được "ảnh chụp nhanh" về nội dung của OuterXml của trình đọc mà không can thiệp vào vị trí của nó?

Trả lời

10

Trên thực tế ReadSubtree sẽ trả về một trình đọc "kết thúc tốt đẹp" trình đọc gốc. Vì vậy, đọc qua một cái mới sẽ kết thúc tiến lên bản gốc là tốt. Bạn phải xem xét XmlReader như một người đọc chỉ chuyển tiếp, nó chỉ đơn giản là không thể quay trở lại. Đối với kịch bản của bạn, thay vì cố gắng nhớ một phần của XML, bạn có thể yêu cầu người đọc cho vị trí trong tệp đầu vào. Chỉ cần đưa nó vào giao diện IXmlLineInfo, nó có các phương thức để trả về dòng và vị trí. Sử dụng điều này bạn có thể nhớ một số vị trí bắt đầu (trước khi các yếu tố trong câu hỏi) và sau đó là vị trí kết thúc của lỗi. Và sau đó đọc phần đó từ tệp tham chiếu dưới dạng văn bản thuần túy.

+0

có, hoàn hảo, cảm ơn bạn, đó là chính xác những gì đã xảy ra. cảm ơn vì lời giải thích! – andy

+0

Ah .. Tôi hoàn toàn hiểu sai điểm của ReadSubTree rồi .. xin lỗi về điều đó.Thành thật mà nói, nó không làm cho điều này rõ ràng từ tài liệu trong trình duyệt đối tượng, nhưng trang MSDN làm cho nó rõ ràng hơn. – Flynn1179

+1

Tôi vừa quay lại và có một cái nhìn khác về mã tôi đã sử dụng nó; nó thực sự ngừng đọc hoàn toàn sau khi nó kết thúc với subtree, vì vậy tôi không bao giờ nhận thấy nó đã nâng cao người đọc ban đầu quá. – Flynn1179

3

Không sử dụng bất kỳ thao tác 'Đọc' nào trên trình đọc - như bạn đã phát hiện, điều này sẽ tiến hành. Sử dụng các cuộc gọi đến các thuộc tính như reader.HasValuereader.Value để kiểm tra nội dung. Tra cứu 'XmlReader' trong trình duyệt đối tượng, có khá nhiều thuộc tính bạn có thể đọc.

Chỉnh sửa: Tôi không nghĩ rằng có một cách đơn giản để nhận XML, có thể vì nút hiện tại có thể không phải là XML hợp lệ trên chính nó, chẳng hạn như nút XmlWhiteSpace, XmlText hoặc thậm chí XmlAttribute.

+0

cảm ơn flynn ... vì mục đích của tôi, tôi hy vọng sẽ nhận được trích xuất xml không hợp lệ trước khi lỗi được ném khi cố gắng tạo XElement. Bạn đang nói điều đó là không thể? – andy

+1

Có lẽ không phải là không thể; Tôi đang đá bản thân mình vì không nhớ điều này trước đây, nhưng nếu bạn gọi 'reader.ReadSubtree()', nó tạo ra một XmlReader hoàn toàn mới bắt đầu ở bất cứ đâu 'reader' là; bạn có thể đọc tất cả những gì bạn thích mà không ảnh hưởng đến 'người đọc' ban đầu của bạn. Không chắc chắn 100% bạn sẽ sử dụng điều này như thế nào trong hoàn cảnh của mình, nhưng có vẻ như đó là cách để đi. – Flynn1179

0

Thực tế, mặc dù Vitek Karas MSFT là đúng, Helena Kupkova đã xuất bản một Trình đọc dấu trang XML nhỏ gọn trên https://msdn.microsoft.com/en-us/library/aa302292.aspx. Điều này cho phép đi ngược lại bằng cách sử dụng bộ nhớ đệm.

0

Một ý tưởng khác: đọc XML bên ngoài (tiến lên trình đọc), sau đó tạo trình đọc mới từ XML này cho phép bạn "quay lại" và xử lý các phần tử của nút hiện tại.

while (r.ReadToFollowing("ParentNode")) 
{ 
    parentXml = r.ReadOuterXml(); 

    //since ReadOuterXml() advances the reader to the next parent node, create a new reader to read the remaining elements of the current parent 
    XmlReader r2 = XmlReader.Create(new StringReader(parentXml)); 
    r2.ReadToFollowing("ChildNode"); 
    childValue = r2.ReadElementContentAsString(); 
    r2.Close(); 
}     
1

Điều tôi đã đọc chỉ đọc phần tử vào XmlDocument và đọc thay vào đó. Trong trường hợp của tôi, tôi phải chuyển đổi tài liệu luồng thành HTML. Tôi đã phải đọc một phần tử bên trong để gán một "kiểu" cho phần tử HTML cha.

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