CAML query that includes folders in result set

2019-01-23 16:54发布

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.

7条回答
Bombasti
2楼-- · 2019-01-23 17:08

You could try basing your caml query on the Folder Content Type instead,

<FieldRef Name='ContentType' /><Value Type='Text'>Folder</Value>

whilst keeping the

Query.ViewAttributes = "Scope=\"RecursiveAll\""; 
查看更多
ら.Afraid
3楼-- · 2019-01-23 17:12

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."

Did you remove the <Or> tags when you did this? If not it will not run correctly.

Regardless, that does not solve your problem. Have you tried leaving the query empty? Does it return anything?

I have been working on something similar and ran into an issue as well, perhaps it's somewhat related.

查看更多
男人必须洒脱
4楼-- · 2019-01-23 17:14

I've solved this putting:

<QueryOptions>
<IncludeAttachmentUrls>True</IncludeAttachmentUrls>
<Folder/> </QueryOptions>

As query option

I found my question about it on stack overflow:

How can I iterate recursively though a sharepoint list using webservices?

查看更多
SAY GOODBYE
5楼-- · 2019-01-23 17:15

I don't have my dev image to test against, so I might need to revise this later; but I think you could try

query.ViewAttributes = "Scope=\"Recursive\""; 

Retrieving the items will allow you to use SPUtility.GetUrlDirectory(url) to get the folder path for a given item, and parse the folder hierarchy from there.

查看更多
唯我独甜
6楼-- · 2019-01-23 17:17
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());     
    }  
查看更多
在下西门庆
7楼-- · 2019-01-23 17:19

This still seems to an issue in SP 2010. Here's workaround code that will work for 2007 or 2010, based on this MSDN Forums post that uses the web services:

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);
}
查看更多
登录 后发表回答