C# 无法保存对存储在Sharepoint 2010文档库中的XML文档的更改

C# 无法保存对存储在Sharepoint 2010文档库中的XML文档的更改,c#,asp.net,xml,sharepoint-2010,C#,Asp.net,Xml,Sharepoint 2010,我正在从事一个项目,该项目要求所有SQL连接和查询信息都存储在XML文件中。为了使我的项目可配置,我试图创建一种方法,让用户通过一系列文本框配置其sql连接字符串信息(数据源、目录、用户名和密码)。然后,此输入将保存到SQL文档中的相应节点 protected void submitBtn_Click(object sender, EventArgs e) { SPFile file = methods.web.GetFile("MyXMLFile.xml");

我正在从事一个项目,该项目要求所有SQL连接和查询信息都存储在XML文件中。为了使我的项目可配置,我试图创建一种方法,让用户通过一系列文本框配置其sql连接字符串信息(数据源、目录、用户名和密码)。然后,此输入将保存到SQL文档中的相应节点

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);
    }
我可以从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);
    }
此时大多数条件都是空的,因为我还在测试

正如我所说的,代码在最后一行之前都非常有效。在这一点上,我得到了错误“内存流不可扩展”。我知道使用内存流更新存储的文件是不正确的,但我无法找到正确的方法


我曾尝试在上一次会议上实施类似问题中给出的解决方案,但这种情况与我的不同,因此实施对我来说毫无意义。如有任何澄清,将不胜感激

使用以字节数组为参数的
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);
         }
    }
要获取Sharepoint文件的
文件路径
,应该遵循以下原则(我现在没有设置Sharepoint开发环境):

或者像这样使用
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);
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');

我没有测试这段代码,但我在Sharepoint解决方案中使用了它来修改Sharepoint列表中的XML(主要是OpenXML)文档。阅读了解更多信息

您可以研究使用XDocument类而不是XmlDocument类。

我更喜欢它,因为它很简单,而且不需要使用内存流

编辑:您可以像这样附加到文件:

  // 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);
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');
或者,您可以搜索元素并按如下方式更新:

  // 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);
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');

谢谢你的回复,瑞奇。不幸的是,这段代码在“myDoc.Load(strm1)”行中抛出了一个错误,该行表示“XmlException未被用户代码处理:根元素丢失。”我查看了您链接到的那篇博客文章,但这与我试图做的有点不同。我正在尝试使用直接的XML文件,而不是Office文档。抱歉,如果我太胖了,但我看不到连接。更新:发现此错误意味着xml文档的根节点丢失,但我有一个。我甚至通过w3schools验证程序运行了我的xml,并确认它是好的xml。更新2:对于傻笑,我试着删除了?@bmurrell30中的标记对不起-在写入字节后,必须重置
内存流的位置。您可以使用strm1.Position=0执行此操作-我更新了代码我尝试了您更新的代码,现在它将通过此方法而不会抛出错误,但更改不会保存回文档库中的文件。还有其他想法吗?请演示在这种情况下我将如何使用XDocument。我已经浏览了你链接到的msdn页面;我尝试将xml直接加载到XDocument对象中,尝试将其加载到XmlReader对象中(稍后将加载到XDocument),尝试了中所示的WebClient StreamReader示例,并且不断出现错误“的最佳重载匹配…具有一些无效参数。”