2009-10-13 31 views
11

我試圖編寫一個CAML查詢,該查詢針對特定SPList執行,作用域爲特定文件夾,從該點遞歸,並返回所有ListItems(符合條件)和Folders 。包含結果集中的文件夾的CAML查詢

下面是這似乎是它應該工作的查詢(格式化的可讀性)代碼:

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異常「無法完成此操作,請重試。」

如果我然後刪除查看字段,只留下Scope=RecursiveAllFSObjType=1,我得到一個空的結果集。

+0

你有沒有解決過這個問題?我有同樣的問題,除非有解決方案,否則我將需要繼續並實際編寫一個遞歸函數來執行此操作。 – jeremcc 2009-12-30 20:03:42

+0

@codeflunky不幸的是,我從來沒有得到這個工作正常。 – 2010-01-02 05:00:28

+0

@codeflunky如果您確實找到解決方案,請在此處發佈! – 2010-01-02 05:02:24

回答

5

我沒有我的開發圖像來測試,所以我可能需要稍後修改;但我認爲你可以嘗試

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

檢索項目將允許您使用SPUtility.GetUrlDirectory(url)得到的文件夾路徑對於給定的項目,並從那裏解析的文件夾層次。

+1

「遞歸」深入搜索文件夾,但不包括結果集中的文件夾對象。我想在一次往返中獲得所需的所有信息 - 在查詢之上製作數十個API調用並不理想。 – 2009-10-13 01:21:39

+0

如果我可能會問,你是否使用它作爲一些UI元素的提供者,例如可以使用延遲加載的樹視圖?或者你會需要一次拉一切? – gn22 2009-10-13 01:49:52

+0

@Gurdas一切都需要立即提取 – 2009-10-13 13:47:00

1

如果我從查詢中刪除了其他條件,只留下FSObjType = 1,我得到一個COM異常「無法完成此操作,請重試。」

當您這樣做時,您是否刪除了<Or>標籤?如果不是,它將無法正常運行。

無論如何,這並不能解決您的問題。你有沒有試過把查詢留空?它會返回任何東西嗎?

我一直在研究類似的東西,也遇到了issue,也許它有些相關。

+0

是的,我所有的CAML查詢都是以編程方式生成的,以避免語法錯誤,例如多餘的''。這不是一個語法問題。 – 2009-11-01 01:17:30

+0

如果您將查詢留空,您會得到結果集嗎? – Mark 2009-11-01 01:44:33

+0

對不起,遲到的迴應。只有當我刪除所有條件時,我纔會得到一組結果。 – 2009-11-10 14:10:33

5

你可以試試你的基礎CAML查詢該文件夾的內容類型,而不是,

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

同時保持

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

我試過了,結果相同。 – 2009-11-03 14:38:16

+0

這對我有用。我能夠使用RecursiveAll查詢文件夾內嵌入文件夾的文件夾內容類型。 – 2012-02-08 20:39:45

3

我已經解決了這個推杆:

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

由於查詢選項

,我發現我的問題關於它的堆棧溢出:

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

+0

有趣...我會試試這個。什麼是空文件夾標籤應該完成? – 2009-11-10 14:08:58

+0

它應該返回文件夾,但我現在不記得了。 SPList是一個非常複雜和晦澀的web服務,有時是魔術...... :) 如果它不起作用,我會在這裏檢查我的文檔。 – 2009-11-10 16:58:56

1

這似乎仍然是在2010年SP的問題,這是一個使用網絡服務的解決方法的代碼,將在2007年或2010年工作的基礎上,this MSDN Forums post

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); 
} 
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> 

,然後設置視圖屬性範圍,以RecursiveAll

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

應該返回其內容類型從文件夾繼承任何項目(0x0120)

+0

非常感謝Scope ='RecursiveAll' – 2015-11-17 16:17:43

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());  
    }