2009-08-28 44 views
46

Nhiều hàm .NET sử dụng XmlWriter để xuất/tạo xml. Xuất ra vào một tập tin/chuỗi/bộ nhớ là một hoạt động rất:Cách tạo XmlDocument bằng XmlWriter trong .NET?

XmlWriter xw = XmlWriter.Create(PutYourStreamFileWriterEtcHere); 
xw.WriteStartElement("root"); 
... 

Đôi khi, bạn cần phải thao tác các Xml kết quả và do đó muốn tải nó vào một XmlDocument hoặc có thể cần một XmlDocument đối với một số lý do khác, nhưng bạn phải tạo XML bằng cách sử dụng XmlWriter. Ví dụ: nếu bạn gọi hàm trong thư viện của bên thứ ba chỉ xuất ra XmlWriter.

Một trong những điều bạn có thể làm là viết xml vào một chuỗi và sau đó tải nó vào XmlDocument của bạn:

StringWriter S = new StringWriter(); 
XmlWriter xw = XmlWriter.Create(S); 
/* write away */ 
XmlDocument xdoc = new XmlDocument(); 
xdoc.LoadXml(S.ToString()); 

Tuy nhiên điều này là không hiệu quả - lần đầu tiên bạn serialize tất cả các thông tin xml vào một chuỗi, sau đó bạn phân tích lại chuỗi để tạo DOM.

Làm cách nào để bạn có thể trỏ XmlWriter để tạo XmlDocument trực tiếp?

+1

+1 Câu hỏi hay, rất hữu ích. – harpo

Trả lời

77

Dưới đây là ít nhất một giải pháp:

XmlDocument doc = new XmlDocument(); 
using (XmlWriter writer = doc.CreateNavigator().AppendChild()) 
{ 
    // Do this directly 
    writer.WriteStartDocument(); 
    writer.WriteStartElement("root"); 
    writer.WriteElementString("foo", "bar"); 
    writer.WriteEndElement(); 
    writer.WriteEndDocument(); 
    // or anything else you want to with writer, like calling functions etc. 
} 

Rõ ràng XPathNavigator mang đến cho bạn một XmlWriter khi bạn gọi AppendChild()

Tín đi đến Martin Honnen trên : http://groups.google.com/group/microsoft.public.dotnet.xml/browse_thread/thread/24e4c8d249ad8299?pli=1

+1

Thực hiện tốt, tìm tốt đẹp. –

+1

Cảm ơn! Rõ ràng với tôi rằng bạn sẽ có thể sử dụng XmlWriter như một người xây dựng cho XmlDocument nhưng tôi không thể tìm thấy một cách dễ dàng để làm điều đó vì vậy tôi đã kết thúc bằng văn bản để đệm và phân tích cú pháp một lần nữa. Họ có thể làm cho nó dễ tìm hơn một chút. –

+0

Bất cứ ai cũng biết nếu có thể sử dụng xdocument/xelement (sử dụng .NET 3.5 để tải không thể trực tiếp từ bộ nhớ) – baileyswalk

9

Bạn có thể làm điều ngược lại: xây dựng XmlDocument đầu tiên sử dụng DOM, sau đó viết nó vào một XmlWriter:

XmlDocument xdoc = new XmlDocument(); 
... // build the document 

StringWriter S = new StringWriter(); 
XmlWriter xw = XmlWriter.Create(S); 
xdoc.WriteTo(xw); 
+0

Xin lỗi nhưng điều này không trả lời được câu hỏi. Tôi cần phải sử dụng một XmlWriter để tạo ra XML - không phải là một XmlDocument. – Boaz

+4

XmlWriter không được thiết kế để ghi vào XmlDocument, nó được thiết kế để ghi vào Stream hoặc TextWriter. Những gì bạn đang yêu cầu chỉ đơn giản là không thể, tôi chỉ đề xuất một cách tiếp cận khác ... –

+0

Dù sao, nếu bạn có thể tạo XML bằng XmlWriter, tôi không thấy lý do tại sao bạn không thể tạo nó bằng XmlDocument .. –

4

Ý tưởng đằng sau XmlWriter là để chờ đợi cho đến khi bạn đã hoàn thành việc sửa đổi dữ liệu của bạn trước khi bạn bắt đầu viết.

XmlWriter không được xây dựng với suy nghĩ của bạn.

Hoặc

  • Chờ cho đến khi bạn biết những gì dữ liệu của bạn được sẽ trước khi viết

hoặc

  • Hãy làm những gì bạn đang làm
+4

Tôi không đồng ý. XmlWriter là một ví dụ điển hình về mẫu xây dựng và nó có ý nghĩa hoàn hảo để sử dụng nó để xây dựng DOM (XmlDocument hoặc bất kỳ triển khai nào khác). Và tôi có trường hợp sử dụng rất thực tế: Tôi đọc dữ liệu XML và biến đổi nó bằng cách sử dụng một số XslCompiledTransform, ghi vào XmlWriter, trực tiếp xây dựng XmlDocument, mà tôi có thể xử lý và sau đó ghi ra (có thể áp dụng một số XSLT khác trên đầu ra). Có chuyện gì vậy? Và viết ra dòng và sau đó phân tích cú pháp một lần nữa là: a) vô nghĩa (nó không giúp hoặc thiết kế rõ ràng hơn), b) không cần thiết và c) không hiệu quả cao. –

1

Có một gạch dưới ying Stream đối tượng mà XmlWriter đang viết, nếu nó là hai chiều (MemoryStream), bạn có thể chỉ cần định vị lại nó trở về -0- và sau đó sử dụng đối tượng Stream trong XmlDocument.Load (stream).

HTH,

Z

+0

Điều này sẽ dẫn đến sự kém hiệu quả tương tự - kiểm tra lại luồng để xây dựng lại DOM. – Boaz

+0

+1 Đây là cách tôi đã chọn để làm điều đó qua ví dụ được đưa ra trong câu hỏi như là một chuỗi không cần phải được tạo ra như là một trung gian. – stevehipwell

+0

Boaz là đúng, về cơ bản giống như phân tích cú pháp XmlDocument từ một chuỗi –

7

Yo u có thể viết tập tin xml bằng cách sử dụng lớp XMLWriter. Đây là ví dụ cho việc này.

XmlWriterSettings objSetting = new XmlWriterSettings(); 
    objSetting.Indent = true; 
    objSetting.NewLineOnAttributes = true; 

    System.Text.StringBuilder sb = new System.Text.StringBuilder(); 


    using (XmlWriter objWriter = XmlWriter.Create(sb, objSetting)) 
    { 
     //Note the artificial, but useful, indenting 
     objWriter.WriteStartDocument(); 

     objWriter.WriteStartElement("books"); 

     ////////Start Book Element/////// 

     objWriter.WriteStartElement("book"); 

     objWriter.WriteStartAttribute("ISBN"); 
     objWriter.WriteValue("asp1"); 
     objWriter.WriteEndAttribute(); 

     objWriter.WriteStartElement("Title"); 
     objWriter.WriteValue("ASP.NET"); 
     objWriter.WriteEndElement(); 

     objWriter.WriteElementString("ReleaseDate", "11/11/2010"); 

     objWriter.WriteStartElement("Pages"); 
     objWriter.WriteValue(200); 
     objWriter.WriteEndElement(); //price 

     objWriter.WriteEndElement(); //book 
     ////////End Book Element/////// 


     ////////Another Element 

     ////////Start Book Element/////// 

     objWriter.WriteStartElement("book"); 

     objWriter.WriteStartAttribute("ISBN"); 
     objWriter.WriteValue("c#2"); 
     objWriter.WriteEndAttribute(); 

     objWriter.WriteStartElement("Title"); 
     objWriter.WriteValue("C#.NET"); 
     objWriter.WriteEndElement(); 

     objWriter.WriteElementString("ReleaseDate", "10/11/2010"); 

     objWriter.WriteStartElement("Pages"); 
     objWriter.WriteValue(500); 
     objWriter.WriteEndElement(); 

     objWriter.WriteEndElement(); //book 
     ////////End Book Element/////// 



     objWriter.WriteEndElement(); //books 
     objWriter.WriteEndDocument(); 

    } 

    File.WriteAllText(Server.MapPath("BooksList.xml"), sb.ToString()); 
Các vấn đề liên quan