SPWeb.ProcessBatchData Method
2009-01-21 10:00 Virus-BeautyCode 阅读(1348) 评论(1) 编辑 收藏 举报刚才发现这个方法对于文档库有特殊的地方,其他类型的列表可以正常运行,经过查找资料,找到一篇解释,原文地址
http://www.sharepointblogs.com/smc750/archive/2008/04/03/spweb-processbatchdata-a-list-is-a-list-is-a-list.aspx
,意思大概就是说文档库有一个字段FileRef,内容是文件的地址,带后缀的,写成batch字符串的时候要想下面这样
Example Two (Deleting a file from a SharePoint Document Library) using ProcessBatchData
<Batch>
<Method>
<SetList Scope="Request">3010913d-9373-44ec-a799-0bf564cb0d66</SetList>
<SetVar Name="Cmd">DELETE</SetVar>
<SetVar Name="ID">1</SetVar>
<SetVar Name="owsfileref">sites/tester1/myfile.bmp</SetVar>
</Method>
</Batch>
The above will delete a list item from a SharePoint document library. You do not need to supply the ID property of the SPListItem but you must supply the item's "Url Path" field for the "owsfileref" variable. The internal name for the "Url Path" field is "FileRef". The ID variable in the caml is ignored and is basically used to number separate commands.
Example Three (Deleting a file from a SharePoint Document Library) using UpdateListItems
<?xml version="1.0" encoding="UTF-8"?>
<Batch>
<Method ID='1' Cmd='Delete'>
<Field Name='ID'>1</Field>
<Field Name='FileRef'>http://basesmcdev/sites/tester1/myfile.bmp</Field>
</Method>
</Batch>
Example three shows the caml to use when using the lists webservice. Yes it is different syntax. It uses the "Field" element instead of the "SetVar" element. Why? Not sure. This caml gets translated by the Microsoft.SharePoint.SoapServer.ListDataImpl.ConstructCaml method into the caml listed in example two and then passed into the ProcessBatchData method.
如果是普通的列表就可以下面这样写,
Example One (Deleting a file from a SharePoint List) using ProcessBatchData
<?xml version="1.0" encoding="UTF-8"?>
<Batch>
<Method>
<SetList Scope="Request">3010913d-9373-44ec-a799-0bf564cb0d66</SetList>
<SetVar Name="Cmd">DELETE</SetVar>
<SetVar Name="ID">1</SetVar>
</Method>
</Batch>
操作文档库的结果如下
The above will delete a list item from a standard SharePoint list not a document library. You need to supply the guid of the SPList and the ID property of the SPListItem. Unfortunately this does not work with a document library. If you try using this with a document library you will get "The file name you specified could not be used. It may be the name of an existing file or directory, or you may not have permission to access the file."
下面是我收集到的SPWeb.ProcessBatchData ,这个批处理方法的几个链接,上面的这个方法可以批处理很多事情的,可以提高我们的效率,在更新和删除的时候
<?xml version="1.0" encoding="UTF-8"?>
<Batch>
<Method>
<SetList Scope="Request">3010913d-9373-44ec-a799-0bf564cb0d66</SetList>
<SetVar Name="Cmd">DELETE</SetVar>
<SetVar Name="ID">1</SetVar>
</Method>
</Batch>
文档库的批量删除可以写成下面这样
{
using (SPSite site = new SPSite("http://virus/sites/intranet"))
{
using (SPWeb web = site.OpenWeb("team"))
{
site.AllowUnsafeUpdates = true;
web.AllowUnsafeUpdates = true;
SPList list = web.Lists["文档库1"];
StringBuilder sbDelete = new StringBuilder();
sbDelete.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>");
foreach (SPListItem item in list.Items)
{
sbDelete.Append("<Method>");
sbDelete.Append("<SetList Scope=\"Request\">" + list.ID + "</SetList>");
sbDelete.Append("<SetVar Name=\"ID\">" + Convert.ToString(item.ID) + "</SetVar>");
sbDelete.Append("<SetVar Name=\"Cmd\">Delete</SetVar>");
sbDelete.Append("<SetVar Name=\"owsfileref\">"+item.GetFormattedValue("FileRef")+"</SetVar>");
sbDelete.Append("</Method>");
}
sbDelete.Append("</Batch>");
try
{
Console.WriteLine( web.ProcessBatchData(sbDelete.ToString()));
}
catch
{
throw;
}
site.AllowUnsafeUpdates = false;
web.AllowUnsafeUpdates = false;
}
}
});
普通的列表去掉
sbDelete.Append("<SetVar Name=\"owsfileref\">"+item.GetFormattedValue("FileRef")+"</SetVar>");
这行就可以了
发现文档库特殊的地方还真是多啊,splistitem有一个copyto方法,可以拷贝到目标列表库,其他类型列表库就可以正常拷贝,文档库就出问题,我还没有找到解决办法,不知道大家有没有什么好办法呢?说来也怪了,在我的虚拟机里面就可以运行
item.CopyTo(web.Url + "/" + web.Lists["已发布动态"].RootFolder.Url + "/" + item.File.Name);
可以到了另外一台就运行出错,提示没有权限之类的,可以我提升了代码的权限SPSecurity.RunWithElevatedPrivileges也没有用。
SPFile.CopyTo找到解决办法了,实例代码如下
//
//copy the file to the same site document library
{
SPFileCollection sourceFiles = web.GetFolder("DocLib").Files;
foreach (SPListItem item in items)
{
SPFile file = sourceFiles[web.Url + "/" + web.Lists["已发布动态"].RootFolder.Url + "/" + item.File.Name];
file.CopyTo(web.Url + "/" + web.Lists["已过期动态"].RootFolder.Url + "/" + item.File.Name, true);
}
}
还有就是要注意name和url的区别,SPWeb.GetFolder方法的参数为Folder的url(是指在地址栏中的url,不是文件夹的显示名称),SPWeb.Lists[]的参数是name(是指列表的显示名称),不能弄混啊。
要是在新建列表的时候输入的就是英文的话,比如说输入“DocLibReleased”代表发布文档库,然后再修改名称为“发布文档库”,
SPWeb.GetFolder("DocLibReleased")返回值就是文档库的文件夹SPFolder,SPWeb.Lists["发布文档库"]返回的就是文档库的列表SPList
我得出一点经验吧,就是建立列表、视图、内容类型、字段的时候最好是用英文,然后再改显示名称为中文,我们还是可以在代码中用新建的时候使用的英文名称访问他们,中文显示名称改成任意的都没有影响,方便代码的移植和通用性。
using (SPSite spSite = new SPSite("http://destination site url/"))
{
string destinationUrl = "some destination url/" + spFile.Name;
SPFileCollection spFiles = spSite.AllWebs["site relative url"].GetFolder("Doc Lib Name").Files;
byte[] bFile = spFile.OpenBinary(); //spFile is the source file
spFiles.Add(destinationUrl, bFile, true);
}
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.processbatchdata.aspx
http://msdn.microsoft.com/en-us/library/cc404818.aspx
http://www.cnblogs.com/netdazhi/articles/1340384.html
二、低效的删除陷阱
foreach(SPListItem item in list.Items)
{
list.Items.DeleteItemById();
}
那么什么是高效的删除操作呢,就是用
SPWeb web;
web.ProcessBatchData();
spweb中的批处理方法,效率要高300%多呢,详细代码如下:
代码引用自
http://www.cnblogs.com/laputa-sky/archive/2008/10/21/1299867.html
From :http://blog.thekid.me.uk/archive/2007/02/24/deleting-a-considerable-number-of-items-from-a-list-in-sharepoint.aspx
Recently the question was asked in the newsgroups about deleting a large number of items from SharePoint (WSS) in the fastest way. I had, in one if my projects, needed to remove a large number of item from SharePoint and the best way I found was to use 'ProcessBatchData' as it avoided the API and was considerably faster.
Here is some example code which will remove items from a SharePoint list. If you do this I would remember about the Recycle Bin and the effect deleting many items will have in the futureit maybe worth adding some code which also removes the items from the recycle bin once it has finished.
StringBuilder sbDelete = new StringBuilder();
sbDelete.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>");
foreach (SPListItem item in CurrentList.Items)
{
sbDelete.Append("<Method>");
sbDelete.Append("<SetList Scope=\"Request\">" + CurrentList.ID + "</SetList>");
sbDelete.Append("<SetVar Name=\"ID\">" + Convert.ToString(item.ID) + "</SetVar>");
sbDelete.Append("<SetVar Name=\"Cmd\">Delete</SetVar>");
sbDelete.Append("</Method>");
}
sbDelete.Append("</Batch>");
try
{
SPContext.Current.Site.RootWeb.ProcessBatchData(sbDelete.ToString());
}
catch (Exception ex)
{
Console.WriteLine("Delete failed: " + ex.Message);
throw;
}
I took me some time to re-find this code and so I have posted it here more for my benefit, but if anyone finds it useful then great.