2014-07-02 209 views
0

我正在處理一個需要將所有SQL連接和查詢信息存儲在XML文件中的項目。爲了讓我的項目可配置,我試圖創建一種方法讓用戶通過一系列文本框配置他的sql連接字符串信息(數據源,目錄,用戶名和密碼)。此輸入將被保存到SQL文檔中的相應節點。無法保存對Sharepoint 2010文檔庫中存儲的XML文檔的更改

我可以從XML文件中獲取當前信息,並在文本框中顯示該信息以供用戶查看和更正,但在保存更改時遇到錯誤。

這裏是我用來更新和保存xml文檔的代碼。

protected void submitBtn_Click(object sender, EventArgs e) 
    { 
     SPFile file = methods.web.GetFile("MyXMLFile.xml"); 
     myDoc = new XmlDocument(); 
     byte[] bites = file.OpenBinary(); 
     Stream strm1 = new MemoryStream(bites); 
     myDoc.Load(strm1); 

     XmlNode node; 
     node = myDoc.DocumentElement; 

     foreach (XmlNode node1 in node.ChildNodes) 
     { 
      foreach (XmlNode node2 in node1.ChildNodes) 
      { 
       if (node2.Name == "name1") 
       { 
        if (node2.InnerText != box1.Text) 
        { 

        } 
       } 

       if (node2.Name == "name2") 
       { 
        if (node2.InnerText != box2.Text) 
        { 

        } 
       } 

       if (node2.Name == "name3") 
       { 
        if (node2.InnerText != box3.Text) 
        { 
         node2.InnerText = box3.Text; 
        } 
       } 

       if (node2.Name == "name4") 
       { 
        if (node2.InnerText != box4.Text) 
        { 

        } 
       } 
      } 
     } 

     myDoc.Save(strm1); 
    } 

此時大部分條件都是空的,因爲我仍在測試。如我所說,代碼很有效,直到最後一行。此時,我收到錯誤「內存流不可擴展」。我明白,使用內存流來更新存儲的文件是不正確的,但我無法找出正確的方法來做到這一點。

我試着在Memory stream is not expandable的類似問題中實現解決方案,但是這種情況與我的不同,因此實現對我來說沒有任何意義。任何澄清將不勝感激。

回答

0

使用將字節數組作爲參數的MemoryStream構造函數創建一個不可調整大小的MemoryStream實例。由於您正在對文件進行更改(因此對底層字節進行更改),因此需要調整大小MemoryStream。這可以通過使用MemoryStream類的無參數構造函數並將字節數組寫入MemoryStream來完成。

試試這個:

SPFile file = methods.web.GetFile("MyXMLFile.xml"); 
    myDoc = new XmlDocument(); 
    byte[] bites = file.OpenBinary(); 

    using(MemoryStream strm1 = new MemoryStream()){ 
     strm1.Write(bites, 0, (int)bites.Length); 
     strm1.Position = 0; 
     myDoc.Load(strm1); 

     // all of your edits to the file here 
     strm1.Position = 0; 

     // save the file back to disk 
     using(var fs = new FileStream("FILEPATH",FileMode.Create,FileAccess.ReadWrite)){ 
       myDoc.Save(fs); 
     } 
    } 

要獲得FILEPATH爲SharePoint文件,這將會是沿着這些路線的東西(我沒有一個SharePoint開發環境的搭建,現在):

SPFile file = methods.web.GetFile("MyXMLFile.xml") 
var filepath = file.ParentFolder.ServerRelativeUrl + "\\" + file.Name; 

或者,它可能會更容易只使用SPFile類的SaveBinary方法是這樣的:

// same code from above 

    // all of your edits to the file here 
    strm1.Position = 0; 
    // don't use a FileStream, just SaveBinary 
    file.SaveBinary(strm1); 

我沒有測試這段代碼,但是我在Sharepoint解決方案中使用它來修改Sharepoint列表中的XML(主要是OpenXML)文檔。閱讀this blogpost以獲取更多信息

+0

感謝您的答覆,rwisch。不幸的是,這段代碼在「myDoc.Load(strm1)」這行中拋出一個錯誤,它說「XmlException被用戶代碼未處理:根元素缺失。」我查看了你鏈接到的博客文章,但與我正在嘗試做的有點不同。我正在嘗試使用直接的XML文件,而不是Office文檔。對不起,如果我很厚,但我沒有看到連接。 – bmurrell30

+0

更新:發現此錯誤意味着xml文檔的根節點丟失,但我有一個。我甚至通過w3schools驗證器運行我的xml,並確認它是很好的xml。那麼是什麼給了? – bmurrell30

+0

更新2:對於咯咯笑,我嘗試刪除?標記來自<?xml聲明,所以我將不得不使用明確的關閉標記。沒有變化 – bmurrell30

0

您可以使用XDocument類而不是XmlDocument類進行研究。 http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx

我更喜歡它,因爲它的簡單性,它消除了使用內存流。

編輯:您可以附加到像這樣的文件:

XDocument doc = XDocument.Load('filePath'); 
       doc.Root.Add(
        new XElement("An Element Name", 
         new XAttribute("An Attribute", "Some Value"), 
         new XElement("Nested Element", "Inner Text")) 
        ); 
       doc.Save(filePath); 

或者你可以搜索元素和更新這樣的:

doc.Root.Elements("The element").First(m => 
    m.Attribute("An Attribute").Value == "Some value to match").SetElementValue(
      "The element to change", "Value to set element to"); 
doc.Save('filePath'); 
+0

請演示如何在這種情況下使用XDocument。我已經通過你鏈接到的msdn頁面;我已經嘗試將xml直接加載到XDocument對象中,我嘗試將它加載到XmlReader對象中(以後要加載到XDocument中),並且我嘗試了http:// social中顯示的WebClient StreamReader示例。 technet.microsoft.com/wiki/contents/articles/19753.read-xml-file-from-document-library-all-sharepoint-version.aspx,我不斷收到錯誤「最好的重載匹配...一些無效的論點。「 – bmurrell30

+0

我編輯了我的答案來展示一個例子。 –

相關問題