Friday, October 18, 2013

From SwearPoint to SharePoint Series - CAML query with nested AND’s /OR’s.

If you ever need to dynamically generate nested AND’s or OR’s in C# might not be an easy task since you are not allow to have more than two conditions. 

In the following example A AND B AND C AND D AND E AND F.

Invalid:

<And>
 <A>
 <B>
 <C>
<D>
<E>
<F>
</And>

Valid:

<And>
 <And>
  <A>
  <B>
 </And>
<And>
 <And>
  <C>
  <D>
 </And>
 <And>
  <E>
  <F>
 </And>
</And>
</And>

I wrote this code and I tested it extensively. I did try it with 120+ statements with no issue.



private string CreateNestedCAMLJoins(List<string> myConditionList, string beginTag, string endTag)
        {
            string CAML = string.Empty;
            string currentCondition = String.Empty;
            Stack myStackOne = new Stack();
            Stack myStackTwo = new Stack();
            Stack myStackThree = new Stack();
            foreach (var myItem in myConditionList)
            {
                myStackOne.Push(myItem);
            }
            bool doLoop = true;
            try
            {
                while (true)
                {
                    if (myStackOne.Count == 0 && myStackTwo.Count == 0 && myStackThree.Count == 1)
                    {
                        CAML = myStackThree.Pop().ToString();
                        doLoop = false;
                        break;
                    }
                    else if (((myStackOne.Count == 0 || myStackOne.Count == 1) && myStackThree.Count >= 1) && myStackTwo.Count == 0)
                    {
                        for (int i = 1; i <= myStackThree.Count; i++)
                        {
                            myStackOne.Push(myStackThree.Pop().ToString());
                        }
                    }
                    else if (myStackOne.Count == 0 && myStackThree.Count == 0)
                    {
                        foreach (var myItemOnStackThree in myStackThree)
                        {
                            CAML += myItemOnStackThree;
                        }
                        doLoop = false;
                    }
                    else if (myStackOne.Count == 1 && myStackThree.Count == 1)
                    {
                        myStackOne.Push(myStackThree.Pop().ToString());
                    }
                    if (myStackTwo.Count == 0)
                    {
                        myStackTwo.Push(endTag);
                    }
                    else if (myStackTwo.Count == 3)
                    {
                        myStackTwo.Push(beginTag);
                        currentCondition = String.Empty;
                        foreach (var caml in myStackTwo)
                        {
                            currentCondition += caml;
                        }
                        myStackThree.Push(currentCondition);
                        myStackTwo.Clear();
                    }
                    else
                    {
                        myStackTwo.Push(myStackOne.Pop().ToString());
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception("<your message>");
            }
            return CAML;
        }


Feel free to use the code; just remember to give credit when credit is deserved :)

No comments:

Post a Comment