代码之家  ›  专栏  ›  技术社区  ›  Marian Polacek

CAML查询:如何从结果集中筛选文件夹?

  •  22
  • Marian Polacek  · 技术社区  · 17 年前

    我使用caml查询来选择用户修改或添加的所有文档。查询在指定网站集的所有子网站上递归运行。

    现在的问题是,我无法摆脱也是结果集一部分的文件夹。目前,我正在从结果数据表中过滤它们。但我想知道:仅仅使用caml就可以从结果集中过滤出文件夹吗?

    8 回复  |  直到 17 年前
        1
  •  24
  •   Nk SP Johan Leino    10 年前

    这个CAML实际上做到了:

    <Where>
        <Eq>
            <FieldRef Name='FSObjType' />
            <Value Type='Integer'>0</Value>
        </Eq>
    </Where>
    

    这不会给你任何文件夹。

        2
  •  12
  •   Alex    7 年前

    所以,我想出来了:) 您可以在caml查询中使用FieldRef='ContentType',并指定要选择或从选择中排除的内容类型的类型。

    因此,在我的例子中,我在caml表达式中添加了这个条件:

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

    注: 多语言设置中存在问题。内容类型的名称可以不同,因此最好从资源中获取内容类型的名字

    更新:

    看起来我的假设太快了。我需要根据文件夹内容类型过滤掉所有内容类型,因为在我们的项目中使用了这样的内容类型:(

    我无法在caml中创建可用的查询,因此我在查询中添加了viewfield元素,该元素选择列表项的ContentTypeId,并过滤出基于文件夹内容类型的行。

    执行此操作的代码很琐碎,但让我感到困扰的是,如此简单的任务无法由纯caml完成。

        3
  •  5
  •   JohnC agilejoshua    12 年前

    根据输出 CAML Designer (由Karine Bosch和Andy Van Steenbergen创建,由Belux信息工作者用户组分发)正确的CAML语法为:

    <Where>
      <Eq>
        <FieldRef Name='FSObjType' />
        <Value Type='Integer'>0</Value>
      </Eq>
    </Where>
    <QueryOptions>
      <ViewAttributes Scope='RecursiveAll' />
    </QueryOptions>
    

    我在PowerShell中测试了这个,得到了预期的结果:

    $qry = new-object Microsoft.SharePoint.SPQuery
    $qry.Query = "<Where><Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>0</Value></Eq></Where><QueryOptions><ViewAttributes Scope='RecursiveAll' /></QueryOptions>"
    
    $items = $lib.GetItems($qry)
    $items.Count
    

    您可以更换 <QueryOptions> 如果愿意,可以在CAML中使用SPQuery对象属性ViewAttributes标记,即 $qry.ViewAttributes = “Scope=’RecursiveAll’" .

    测试时,请确保每次都重新实例化SPQuery对象,因为您不能简单地重新分配Query属性。执行查询后,将忽略分配给query属性的任何新值。因此,请执行整个PowerShell片段。

        4
  •  4
  •   Peter Jacoby    15 年前

    如果您正在使用文件夹并且使用SPQuery对象,您可能还希望使用ViewAttributes字段来允许递归项目检索。将值设置为Scope=“Recursive”将从子文件夹中检索项目,而不会检索结果集中的文件夹对象。

    myQuery.ViewAttributes = "Scope=\"Recursive\"";
    
        5
  •  2
  •   Community Mohan Dere    8 年前

    Dave T.'s answer 这对我来说并不奏效,但我把它当作一种灵感,以下是我的想法:

    <Where>
      <BeginsWith><FieldRef Name="ContentTypeId" />
        <Value Type="ContentTypeId">0x0101</Value>
      </BeginsWith>
    </Where>
    

    主要问题是我们只能知道 站点级别的ContentTypeId ,因为当一个内容类型被添加到列表/库中时,它就变成了 列表内容类型 并且其ID附加有另一个GUID(0x010100…)。还有 没有开始 CAML中的条件,因此我们无法过滤出文件夹,但我们可以包含 仅文档 哪个站点内容类型id是 0x0101 .

    解决方案与 FSObjType 字段对我不起作用,因为我的库中的文件远远超过阈值,所以查询中的所有字段都必须被索引,而我还没有找到索引此字段的方法。

        6
  •  0
  •   Alex Nolasco    15 年前

    这对我来说是有效的

       <Where>
          <Eq>
             <FieldRef Name='FSObjType' />
             <Value Type='Number'>1</Value>
          </Eq>
       </Where>
    
        7
  •  0
  •   Community Mohan Dere    8 年前

    检查我的其他答案 CAML query that includes folders in result set

    只需更换操作员,即可满足您的需求

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

    我不确定这是否可行。

        8
  •  0
  •   Ole Albers    9 年前

    对我来说,它也像下面写的那样工作:-

    <Where><Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>1</Value></Eq></Where>