I'm trying to write a CAML query that executes against a specific SPList, scoped to a specific folder, recursive from that point, and returns all ListItems (which meet a criteria) and Folders.
Here's the code for the query which seems like it should work (formatted for readability):
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();
So - this only returns the ListItems - no folders.
If I remove the other conditions from the query, only leaving the FSObjType=1
, I get a COM exception "Cannot complete this action. Please try again."
If I then remove the ViewFields, leaving only the Scope=RecursiveAll
and FSObjType=1
, I get an empty result set back.
每个人都很近,但并不完全正确。
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>
然后,设置视图属性范围,以RecursiveAll
<View Scope='RecursiveAll'>...</View>
这应该返回其内容类型从文件夹继承任何项目(0x0120)
我没有我的dev的形象,以测试对,所以我可能需要以后修改本; 但我认为你可以尝试
query.ViewAttributes = "Scope=\"Recursive\"";
检索项目将允许您使用SPUtility.GetUrlDirectory(url)
来获取文件夹路径对于给定的项目,并从那里解析的文件夹层次。
你可以尝试在该文件夹内容类型基础的CAML查询,而不是,
<FieldRef Name='ContentType' /><Value Type='Text'>Folder</Value>
同时保持
Query.ViewAttributes = "Scope=\"RecursiveAll\"";
我已经解决了这个推杆:
<QueryOptions>
<IncludeAttachmentUrls>True</IncludeAttachmentUrls>
<Folder/> </QueryOptions>
由于查询选项
我发现我的问题关于它的堆栈溢出:
我怎样才能使用,虽然web服务SharePoint列表递归迭代?
如果我从查询中删除的其他条件,只留下FSObjType = 1,我得到一个COM异常“无法完成此操作,请重试。”
你删除<Or>
标签,当你这样做? 如果不将无法正常运行。
无论如何,这并不解决您的问题。 您是否尝试过离开的查询是空的? 是否任何回报?
我一直在努力类似的东西,并遇到了一个问题,还有,也许是有点关系。
这似乎仍然在2010年SP的问题,这里有解决方法的代码,将在2007年或2010年工作的基础上, 这个MSDN论坛发布使用Web服务:
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);
}
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());
}