结果集中包含文件夹的 CAML 查询

发布于 2024-08-07 01:26:28 字数 1134 浏览 1 评论 0原文

我正在尝试编写一个针对特定 SPList 执行的 CAML 查询,范围限定为特定文件夹,从该点递归,并返回所有 ListItems(满足条件)和文件夹。

这是查询的代码,看起来应该可以工作(为了便于阅读而格式化):

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=RecursiveAllFSObjType=1,我会得到一个空结果集。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

妖妓 2024-08-14 01:26:28

每个人都很接近,但又不完全正确。

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>

这应该返回内容类型继承自文件夹 (0x0120) 的任何项目

Everyone is close, but not quite right.

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
}

First of all, using this FieldRef is wrong:

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

because the folder content type can be inherited. Therefore, you need to compare against the content type ID, like this:

<Where>
  <BeginsWith>
    <FieldRef Name='ContentTypeId' />
    <Value Type='ContentTypeId'>0x0120</Value>
  </BeginsWith>
</Where>

And then, set the view attribute Scope to RecursiveAll

<View Scope='RecursiveAll'>...</View>

That should return any item whose content type inherits from Folder (0x0120)

断爱 2024-08-14 01:26:28

我没有可供测试的开发映像,因此我可能需要稍后修改它;但我认为您可以尝试

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

检索项目将允许您使用 SPUtility.GetUrlDirectory(url) 来获取给定项目的文件夹路径,并从那里解析文件夹层次结构。

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.

执手闯天涯 2024-08-14 01:26:28

您可以尝试将 caml 查询基于文件夹内容类型,同时

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

保留

Query.ViewAttributes = "Scope=\"RecursiveAll\""; 

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\""; 
不忘初心 2024-08-14 01:26:28

我已经解决了这个问题:

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

作为查询选项,

我在堆栈溢出上发现了关于它的问题:

如何使用 Web 服务递归地遍历共享点列表?

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?

赠佳期 2024-08-14 01:26:28

如果我从查询中删除其他条件,仅保留 FSObjType=1,则会收到 COM 异常“无法完成此操作。请重试。”

执行此操作时,您是否删除了 标签?如果不是,它将无法正确运行。

无论如何,这并不能解决你的问题。您是否尝试过将查询留空?它返回什么吗?

我一直在研究类似的事情,并遇到了 问题 同样,也许有些相关。

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.

黑寡妇 2024-08-14 01:26:28

这在 SP 2010 中似乎仍然是一个问题。以下是适用于 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);
}

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);
}
旧时模样 2024-08-14 01:26:28
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());     
    }  
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());     
    }  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文