为 SharePoint 中的列表查询构建 CAML






3.47/5 (6投票s)
以优化、高效和最简单的方式编写 CAML 查询。
引言
手工(打字)编写 CAML 查询一直以来都是件痛苦的事。虽然网上有很多工具可以做到这一点,但开发人员仍然需要自己手动输入。工具只能帮助选择查询运算符和调试。没有拖放选项或 UI 来构建整个查询。在这篇文章中,我将展示如何无需输入即可构建 CAML 查询。我可以向您保证,它的优化程度一定比自己手动输入要高。目标受众是那些已经熟悉 CAML 和创建列表视图的人。
CAML 查询用法
我们可以在任何地方使用 **CAML 查询**,例如 **SOM** (服务器对象模型)、**CSOM** (客户端对象模型)、**JSOM** (JavaScript 对象模型和 **REST API**) 。无论我们把它用在哪里,语法始终是一样的。让我们回顾一下我们的代码……
服务器端对象模型
var spQuery = new SPQuery();
spQuery.Query = string.Concat("CAML Query goes here");
var listItems = spWeb.Lists["List Name"].GetItems(spQuery);
客户端对象模型
CamlQuery query = CamlQuery();
query.ViewXml = string.Concat("CAML Query goes here");
var listItems = spList.GetItems(query);
clientContext.Load(listItems);
clientContext.ExecuteQuery();
JavaScript 对象模型
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('CAML Query goes here');
this.collListItem = oList.getItems(camlQuery);
clientContext.load(collListItem);
REST API SharePoint 2013
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/Web/Lists/getbytitle('List Name')/GetItems",
type: "POST",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"content-Type": "application/json;odata=verbose"
},
data: JSON.stringify({
query : {
__metadata: {
type: "SP.CamlQuery"
},
ViewXml: 'CAML Query goes here'
}
}),
success: function (data) {
console.log(data);
},
error: function (error) {
alert(JSON.stringify(error));
}
});
现在我们将看到如何无需手动输入即可构建我们的 CAML 查询。
CAML 构建实操
方法非常直接。我们只需创建一个列表视图,然后从中获取 **CAML 查询**。让我们来看看实际操作。
1. 进入列表设置,然后点击 **创建视图**
2. 选择 **标准** **视图**,输入 **视图名称** 并选择 **公共视图**
3. 选择您想在 **CAML** **查询** 中使用的 **列**
4. 从 **排序** 部分选择 **列名称** 并选择 **升序** 或 **降序** 选项
这等同于<OrderBy>
元素
<OrderBy>
<FieldRef Name="Field Name"/>
<FieldRef Name="Field Name" Ascending="FALSE"/>
<FieldRef Name="Field Name" Ascending="TRUE"/>
</OrderBy>
5. 现在从 **筛选** 部分选择 **列名称**、**条件** 并选择 **值**
这等同于<Where>
元素
<Query>
<Where>
<Geq>
<FieldRef Name="Field Name"/>
<Value Type="DateTime">
<Today/>
</Value>
</Geq>
</Where>
<OrderBy>
<FieldRef Name="Field Name"/>
</OrderBy>
</Query>
让我们看一些 **视图** 和 **CAML** 之间的等效条件
条件 |
等效 CAML 查询 |
等于 |
|
不等于 |
|
大于 |
|
小于 |
|
大于或等于 |
|
小于或等于 |
|
开头是 |
|
contains |
|
要检查 `null`,只需将值留空
这等同于 `<IsNull> `和 `<IsNotNull> `元素
<Or>
<IsNull><FieldRef Name="Employee" /></IsNull>
<IsNotNull><FieldRef Name="ID" /></IsNotNull>
</Or>
6. 如果需要,您可以从 **分组依据** 部分进行 **分组依据**
这等同于 `GroupBy` 元素
<GroupBy Collapse="TRUE" GroupLimit="30">
<FieldRef Name="Title" />
</GroupBy>
从视图中获取 CAML 查询
可以通过多种方式从视图中获取 CAML 查询。我首选的方式是 PowerShell。所以让我们从 PowerShell 开始。打开 PowerShell 并粘贴以下脚本,它将在文本文件中生成我们的 CAML 查询。
$spWeb = Get-SPWeb -Identity "Site URL goes here";
$spList = $spWeb.Lists["List Name"];
$spView = $spList.Views["View Name"];
$spView.Query | Out-File "Path with file name"
现在打开文本文件,并在 **SOM**、**CSOM**、**JSOM** 或 **REST API** 中使用它
如果您不熟悉 PowerShell,您可以使用任何 REST 客户端,例如 Chrome 的 Advanced Rest Client 或 fiddler。下面的示例演示了 Advanced Rest Client。此示例适用于 **SharePoint 2013**。
API 端点是
http://Site URL/_api/Web/Lists/getbytitle('List Name')/Views/getbytitle('View Name')?$select=ViewQuery
标头将是 `Accept: application/json;odata=verbose` 以 JSON 格式获取结果
现在点击 **发送** 按钮,它将返回如下 JSON 格式的结果
{
"d": {
"__metadata": {
"id": "http://site url/_api/Web/Lists(guid'ec945846-bea2-4d3d-ba02-6e9f6dea9541')/Views(guid'91eb23c1-b489-4eb6-9f9a-571c32db6a4f')",
"uri": "http://site url/_api/Web/Lists(guid'ec945846-bea2-4d3d-ba02-6e9f6dea9541')/Views(guid'91eb23c1-b489-4eb6-9f9a-571c32db6a4f')",
"type": "SP.View"
},
"ViewQuery": "<GroupBy Collapse=\"TRUE\" GroupLimit=\"30\"><FieldRef Name=\"Title\" /></GroupBy><OrderBy><FieldRef Name=\"ID\" /></OrderBy><Where><Or><IsNull><FieldRef Name=\"Employee\" /></IsNull><IsNotNull><FieldRef Name=\"ID\" /></IsNotNull></Or></Where>"
}
}
只需复制返回 JSON 中的 `ViewQuery` 值即可使用。
# 更新
**Advanced Rest Client** 在新版本中存在身份验证问题。它不能与 SharePoint 无缝工作。所以我自己制作了 Chrome 的 **SP REST Client**。您可以使用它非常轻松地探索/测试 REST API。我的 SP REST Client 的文档可以在这里找到。
CAML 查询可以通过 **REST API** 和 **jQuery** 在 **SharePoint 2013** 中获取。您可以参阅我关于 REST API 的另一篇文章这里。如果您的网站中包含 **jQuery**,请将以下代码粘贴到您的浏览器控制台中。
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/Web/Lists/getbytitle('list name')/Views/getbytitle('view name')?$select=ViewQuery",
type: "GET",
headers: {
"accept": "application/json;odata=verbose",
},
success: function (data) {
console.log(data.d);
},
error: function (error) {
alert(JSON.stringify(error));
}
});
对于 **SharePoint 2010**,以下方法将有助于从视图中获取 CAML 查询。
function getCamlQueryFromView(listTitle, viewTitle) {
var context = new window.SP.ClientContext.get_current();
var list = context.get_web().get_lists().getByTitle(listTitle);
var view = list.get_views().getByTitle(viewTitle);
context.load(view);
context.executeQueryAsync(
function(sender, args) {
console.log(view.get_viewQuery())
},
function(sender, args) {
alert("error: " + args.get_message());
}
);
}
上述代码也适用于 **SharePoint 2013**。由于方法因 **SharePoint** 版本而异,我始终倾向于使用 PowerShell。
好了,开始用这种方式构建 CAML,并告诉我您的反馈,看看效果如何!
关注点
我必须承认,有些内容我无法以这种方式找到等效项。如果您能实现,请在评论中告诉我,然后我将更新我的文章。其中一些内容在下面列出。
1. Membership Element
2. NotIncludes Element
3. `In Element`
4. `DateRangesOverlap Element`
5. 等其他
如果您需要上述元素用于复杂的 CAML 查询,您必须手动输入。我的建议是:首先尝试我的方法,然后根据需要进行修改。我希望它能为您节省 80% 的工作量。