我正在尝试编写一个CAML查询,该查询针对特定的SPList执行,范围限定为特定文件夹,从该点递归,并返回所有ListItem(符合条件)和文件夹。
以下是查询的代码,它似乎应该可以工作(格式化为可读性):
SPQuery query = new SPQuery();
query.Query = "
<Where>
<Or>
<Contains>
<FieldRef Name=\"FileRef\" />
<Value Type=\"Text\">foo</Value>
</Contains>
<Eq>
<FieldRef Name=\"FSObjType\" />
<Value Type=\"Lookup\">1</Value>
</Eq>
</Or>
</Where>";
query.ViewFields = "
<FieldRef Name=\"CustomField1\" Nullable=\"TRUE\" />
<FieldRef Name=\"CustomField2\" Nullable=\"TRUE\" />
<FieldRef Name=\"CustomField3\" Nullable=\"TRUE\" />
";
query.RowLimit = 500;
query.ViewAttributes = "Scope=\"RecursiveAll\"";
query.Folder = startingFolder;
DataTable dt = myList.GetItems(query).GetDataTable();
所以 - 这只返回ListItems - 没有文件夹。
如果我从查询中删除其他条件,只离开FSObjType=1
,我会收到COM异常“无法完成此操作。请重试。”
如果我删除了ViewFields,只留下Scope=RecursiveAll
和FSObjType=1
,我会得到一个空的结果集。
答案 0 :(得分:14)
每个人都很亲密,但不是很正确。
using (SPSite site = new SPSite("http://server/site"))
{
SPWeb web = site.RootWeb; // See disposal guidance http://blogs.msdn.com/b/rogerla/archive/2008/10/04/updated-spsite-rootweb-dispose-guidance.aspx
SPQuery query = new SPQuery();
query.Query = @"
<Where>
<BeginsWith>
<FieldRef Name='ContentTypeId' />
<Value Type='ContentTypeId'>0x0120</Value>
</BeginsWith>
</Where>";
query.ViewAttributes = "Scope='RecursiveAll'";
SPList list = web.Lists[listId];
SPListItemCollection items = list.GetItems(query);
// Do stuff with your folders
}
首先,使用此FieldRef是错误的:
<FieldRef Name='ContentType' /><Value Type='Text'>Folder</Value>
因为可以继承文件夹内容类型。因此,您需要与内容类型ID进行比较,如下所示:
<Where>
<BeginsWith>
<FieldRef Name='ContentTypeId' />
<Value Type='ContentTypeId'>0x0120</Value>
</BeginsWith>
</Where>
然后,将视图属性Scope设置为RecursiveAll
<View Scope='RecursiveAll'>...</View>
应返回内容类型继承自Folder(0x0120)
的任何项目答案 1 :(得分:5)
我没有我的开发图像进行测试,所以我可能需要稍后修改它;但我想你可以试试
query.ViewAttributes = "Scope=\"Recursive\"";
检索项目将允许您使用SPUtility.GetUrlDirectory(url)
获取给定项目的文件夹路径,并从那里解析文件夹层次结构。
答案 2 :(得分:5)
您可以尝试将您的caml查询基于文件夹内容类型,
<FieldRef Name='ContentType' /><Value Type='Text'>Folder</Value>
同时保持
Query.ViewAttributes = "Scope=\"RecursiveAll\"";
答案 3 :(得分:3)
我已经解决了这个问题:
<QueryOptions>
<IncludeAttachmentUrls>True</IncludeAttachmentUrls>
<Folder/> </QueryOptions>
作为查询选项
我在堆栈溢出时发现了我的问题:
How can I iterate recursively though a sharepoint list using webservices?
答案 4 :(得分:1)
如果我从查询中删除其他条件,只留下FSObjType = 1,我会收到COM异常“无法完成此操作。请重试。”
您执行此操作时是否删除了<Or>
代码?如果不是它将无法正常运行。
无论如何,这并不能解决您的问题。您是否尝试将查询留空?它会返回什么吗?
我一直在做类似的事情并且遇到了issue,也许它有些相关。
答案 5 :(得分:1)
这仍然是SP 2010中的问题。以下是基于使用Web服务的this MSDN Forums post将适用于2007或2010的变通方法代码:
private static SPListItem RecurseIntoFolders(SPList list, SPFolder parentFolder, string fileReference)
{
var query = new SPQuery
{
Query = "<Where>" +
"<Eq><FieldRef Name='FSObjType'/><Value Type='Lookup'>1</Value></Eq>" +
"</Where>",
ViewFields = String.Format("<FieldRef Name='{0}' />", FileReferenceInternalFieldName),
ViewAttributes = "Scope='RecursiveAll'",
Folder = parentFolder
};
var items = list.GetItems(query);
if (items.Count == 0)
return null;
foreach (SPListItem item in items)
{
parentFolder = item.Folder;
// TODO: Any other checking that this is the item we want
return item;
}
return RecurseIntoFolders(list, parentFolder, fileReference);
}
答案 6 :(得分:0)
static string GetParentFolder(SPListItem itemToFind, SPFolder folder)
{
SPQuery query = new SPQuery();
// query.Query = "<OrderBy><FieldRef Name='Title'/></OrderBy>";
query.Query = "<Where><Eq><FieldRef Name=\"ID\"/><Value Type=\"Integer\">"+ itemToFind.ID +"</Value></Eq></Where>";
query.Folder = folder;
query.ViewAttributes = "Scope=\"Recursive\"";
SPListItemCollection items = itemToFind.ParentList.GetItems(query);
int intpartentFolderID=0 ;
if (items.Count > 0)
{
foreach (SPListItem item in items)
{
SPFile f = item.Web.GetFile(item.Url);
string test11 = f.ParentFolder.Name;
intpartentFolderID = f.ParentFolder.Item.ID;
//string test1 = item.File.ParentFolder.Name;
return (intpartentFolderID.ToString());
}
}
return (intpartentFolderID.ToString());
}