簡體   English   中英

使用XmlWriter迭代構建XML文件

[英]Building an XML file iteratively with XmlWriter

我希望能夠使用XmlWriter (C#,.NET)創建一個XML文檔,其中多次調用生成XML的方法,然后調用最終方法來關閉所有內容。 當我嘗試多次調用此方法時:

private void SiblingGenerator(List<XmlNode> XMLList, XmlWriter textWriter,
    string newPath, FileInfo fi)
{
    if (fi.Length == 0)
    {
        MessageBox.Show("file doesn't exist");

        textWriter.WriteStartDocument();
        textWriter.WriteStartElement("batch");
        //...
    }

    // ...
}

...它返回一個錯誤,說WriteStartDocument needs to be the first call

似乎對textWriter的調用實際上並沒有被寫入,因為在每次后續調用中文檔都會重新開始。

誰能告訴我為什么會這樣?

XmlWriter只是前向的,不能重用。 您不應該在此類的同一實例上多次調用WriteStartDocument 因為它是你方法的一個參數,所以調用者必須負責處理作者的生命周期。

using (var writer = XmlWriter.Create("foo.xml"))
{
    SiblingGenerator(XMLList, writer, newPath, fi);
}

如果需要多次重用SiblingGenerator函數,則可能需要外部化WriteStartDocument方法的調用:

using (var writer = XmlWriter.Create("foo.xml"))
{
    writer.WriteStartDocument();
    SiblingGenerator(XMLList, writer, newPath, fi);
    SiblingGenerator(XMLList, writer, newPath, fi);
    ...
    writer.WriteEndDocument();
}

任何類型的“編寫器”對象,如TextWriter,XmlWriter等,都會進行某種程度的緩沖,因為底層流完全不受其控制。 換句話說,您不能依賴底層文件的長度來確定是否已經對作者進行了先前的調用。

但具體來說,System.IO中的許多類都有一個Flush方法,比如Stream和TextWriter,它可以用來將緩沖的內容推送到磁盤,但在我看來,這會產生非常脆弱的代碼。

您應該保留其他類型的狀態以確定您是否已經編寫了文檔的開頭。

有幾件事可以阻止該方法的運作。 XmlWriter可能不直接將代碼寫入流中, FileStream可能不會直接將數據寫入文件,而FileInfo對象會緩存它的信息,因此您必須使其自行更新以獲取最新的信息。

您可以使用布爾變量來跟蹤它是否是第一個項目,而不是使用FileInfo對象來檢查它。

或者,只需在進入調用此方法的循環之前寫入文檔的開頭。

我猜其他錯誤,代碼應該工作。 您可能正在重用XmlWriter。 如果在方法中本地聲明XmlWriter,您仍然會收到錯誤嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM