ExpressionScript 操作指南
From LimeSurvey Manual
前面内容回顾
如果您已按顺序阅读了 LimeSurvey 手册的前面部分,说明您已经了解 LimeSurvey 术语。接下来,我们介绍了表达式和变量,以便学习如何增强您的调查。在下一部分中,我们介绍了语法高亮的类型及含义,以便学习如何纠正语法错误。
掌握这些基本概念之后,我们就可以通过示例来说明表达式在 LimeSurvey 中是如何工作的。
语法高亮
以下截图仅作示例,不显示工具提示的内容。工具提示是一个信息框,当您将鼠标悬停在任何粗体彩色文字上时就会显示。
有了语法高亮,即使是复杂的表达式,也可以很容易地编写正确。尽管 LimeSurvey 团队计划尝试构建表达式构建器图形界面,但您现在就可以利用现有的语法高亮快速找出并修正拼写错误。您还可以使用工具提示来验证表达式的准确性(例如,确认您已选择了所需的变量)。
每个示例都包含三列:
- 源代码 - 即您将输入到 LimeSurvey 问题字段中的原始文本
- 美化输出 - 即您所输入内容经过语法高亮后的等效显示
- 请注意,在此高亮显示中,表达式以棕褐色背景显示,但不带花括号。
- 由于 EM 支持递归替换,在高亮显示中显示花括号会导致语法错误
- 结果 - 即 EM 处理源代码后生成的输出
- 所有可以正确替换的内容都会被替换
- 含有错误的表达式会以语法高亮的方式在行内显示。错误会被红色线框框住。
正确的语法
以下是正确语法的示例:
- 值:显示已知变量会根据其是否已在当前页面设置而以不同颜色标示。
- 问题属性:显示可以通过点号表示法访问问题的某些属性
- 数学运算:显示支持基本和复杂的计算
- 文本处理:显示部分可用的文本处理函数
- 日期:显示两个可用的日期相关函数
- 条件:显示 if() 函数的用法。选项可以嵌套。
- 定制段落:您可以根据先前的值完全自定义报告
- EM 在字符串内处理:显示可以在字符串内进行替换。此示例生成一个定制的图片名称。
- EM 不处理类似这样的花括号:显示如果花括号被转义,或者表达式与花括号之间有空格,ES 将忽略该表达式。

包含错误的 EM 语法
以下是输入 ES 表达式时常见错误的示例。请注意,工具提示会提供额外的信息。
- 忘记在花括号后添加空格的内联 Javascript
- 由于 "document.write" 紧跟在花括号之后,EM 会认为它是一个表达式,并用红框标出 "document" 和 "write",因为它们分别是未定义的变量和函数
- 未知/拼写错误的变量、函数和运算符
- 这里我们忘了自己使用的变量名是 "gender" 而不是 "sex",但 EM 发现了该错误。它还用红框标出了 '++',因为这不是受支持的运算符。
- 如果使用 = 而不是 eq,或执行赋值操作,会发出警告
- 请注意,'=' 和 '+=' 显示为红色文字而不是黑色。将鼠标悬停在它们上面,您会看到您正在赋值的警告。
- 函数的参数数量错误
- if() 需要 3 个参数,但给出了 4 个,因此将鼠标悬停在红框标出的 "if" 上会说明错误并显示支持的语法
- sum() 接受任意数量的参数,但我们在右括号前多了一个逗号,因此该处被红框标出
- 括号不匹配
- 这是编写表达式时最常见的错误之一。
- 这里显示了两个缺少右括号的示例,以及一个多了一个右括号的示例。
- 不支持的语法
- 如果您使用了 ES 不支持的运算符或标点符号,它会用红框标出。
- 无效的赋值
- 某些变量是可读写的,其值可以更改;其他变量则是只读的。
- 如果您试图更改只读变量的值,是无法成功的。EM 会用红框标出该尝试。
- 如果您试图给方程式或字符串赋值,同样会出现错误

带有活动工具提示的语法高亮“实时”示例
| 源代码 | 美化输出 | 结果 |
|---|---|---|
| 以下是带有工具提示的正确语法示例 您好 {if(gender=='M','Mr.','Mrs.')} {surname},现在是 {date('g:i a',time())}。您知道您的 {sum(numPets,numKids)} 个孩子和宠物在哪里吗? | 以下是带有工具提示的正确语法示例 您好 if(gender == 'M','Mr.','Mrs.') surname,现在是 date('g:i a',time())。您知道您的 sum(numPets,numKids) 个孩子和宠物在哪里吗? | 以下是带有工具提示的正确语法示例 您好 Mr. Smith,现在是 6:07 am。您知道您的 3 个孩子和宠物在哪里吗? |
| 以下是常见错误,您可以查看工具提示 在声明之前使用的变量: {notSetYet} 未知函数: {iff(numPets>numKids,1,2)} 未知变量: {sum(age,num_pets,numKids)} 参数数量错误: {sprintf()},{if(1,2)},{date()} 为只读变量赋值:{TOKEN:ATTRIBUTE_1+=10},{name='Sally'} 括号不匹配: {pow(3,4},{(pow(3,4)},{pow(3,4))} | 以下是常见错误示例,您可以查看工具提示 在声明之前使用的变量: notSetYet 未知函数: iff(numPets > numKids,1,2) 未知变量: sum(age,num_pets,numKids) 参数数量错误: sprintf(),if(1,2),date() 为只读变量赋值:TOKEN:ATTRIBUTE_1+=10,name='Sally' 括号不匹配: pow(3,4,(pow(3,4),pow(3,4)) | 以下是常见错误示例,您可以查看工具提示 在声明之前使用的变量: notSetYet 未知函数: iff(numPets > numKids,1,2) 未知变量: sum(age,num_pets,numKids) 参数数量错误: sprintf(),if(1,2),date() 为只读变量赋值:TOKEN:ATTRIBUTE_1+=10,name='Sally' 括号不匹配: pow(3,4,(pow(3,4),pow(3,4)) |
| 以下是部分不支持的语法 不支持 '++', '--', '%',';':{min(++age, --age,age % 2);} 也不支持 '|', '&', '^':{(sum(2 | 3,3 & 4,5 ^ 6)}} 也不支持数组:{name[2], name['mine']} | 以下是部分不支持的语法 不支持 '++', '--', '%',';':min( ++ age, -- age,age % 2) ; 也不支持 '|', '&', '^':(sum(2 | 3,3 & 4,5 ^ 6)} 也不支持数组:name [ 2 ] ,name [ 'mine' ] | 以下是部分不支持的语法 不支持 '++', '--', '%',';':min( ++ age, -- age,age % 2) ; 也不支持 '|', '&', '^':(sum(2 | 3,3 & 4,5 ^ 6)} 也不支持数组:name [ 2 ] ,name [ 'mine' ] |
定制示例
"尊敬的 {Mr}/{Mrs} Smith..."
使用 if() 函数,按条件选择显示 'Mr.' 还是 'Mrs.'。
语法为 if(test,do_if_true,do_if_false)。
| # | 代码 | 问题 | 类型 |
| 1 | gender | 您的性别是? | 性別 |
| 2 | example1 | 尊敬的 {if(gender=='M','Mr.','Mrs.')} Smith,... | 长自由文本 |

如下所示,"Mr" 和 "Mrs" 会根据受访者对问题 "gender" 所选的答案进行定制。

邀请邮件中的 "尊敬的 {Mr}/{Mrs} Smith..."
您可以利用邀請碼表中的属性,在邀请邮件中使用上述示例。使用 if() 函数来选择邮件中应使用 'Mr.' 还是 'Mrs.'。
语法为 "if(test,do_if_true,do_if_false)"。
| # | 属性 | 值 |
| 1 | 姓 | Smith |
| 2 | 邮件地址 | test@test.com |
| 3 | ATTRIBUTE_2 | M |
邀请邮件中的文本:
尊敬的 {if(ATTRIBUTE_2=='M','Mr','Mrs')} {LASTNAME},
我们邀请您参加一项调查:
https:/...

电子邮件查看:

计算 / 评估示例
在运行时计算评估值并将结果存储到调查資料中
此示例使用了 EM 的所有功能,包括相关性、定制以及方程式问题类型。
它还表明所有这些功能都支持 JavaScript,因此如果页面上使用了这些功能,页面内容会随着用户设置和更改答案而动态变化。
| # | 代码 | 问题 | 类型 | 相关性 |
| 1 | numKids | 您有几个孩子? | 数字输入 | 1 |
| 2 | kid1 | 您的第一个孩子多大? | 数字输入 | numKids >= 1 |
| 3 | kid2 | 您的第二个孩子多大? | 数字输入 | numKids >= 2 |
| 4 | kid3 | 您的第三个孩子多大? | 数字输入 | numKids >= 3 |
| 5 | kid4 | 您的第四个孩子多大? | 数字输入 | numKids >= 4 |
| 6 | sumKidAges | {sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK)} | 方程式 | 1 |
| 7 | kidSummary | 您说您有 {numKids}。{if(numKids==1,'child','children')}。{if(numKids>1,implode(' ','The sum of ages of your first ',min(numKids,4),' kids is ',sumKidAges,'.'),' ')} | 文本显示 | 1 |
要下载此示例,请点击以下链接:评估调查示例。
下面是一些具有代表性的问题截图。如您所见,EM 会对所有可能包含定制内容的字段进行语法高亮显示。在这里,您可以看到对相关性(Relevance)、方程式问题类型以及问题内部替换进行语法高亮的示例。您还可以在帮助、群组标题显示、欢迎信息和结束信息中使用替换。
在下一个示例中,由于相关性为 {numKids >= 2),只有当受访者表示她至少有两个孩子时,该问题才会显示。

在下面您可以看到,每个变量都附带了 .NAOK 后缀。这是 EM 支持级联相关性的方式。如果没有 .NAOK,则只有在受访者表示她有 4 个孩子时(即所有变量都相关时)才会计算总和。使用 .NAOK 意味着即使所有或部分变量不相关,我们也要计算总和(即“不适用”(NA)也是可以的(OK))。
不过,.NAOK 属性只影响变量是否被传递给 EM。如果受访者起初说她有 3 个孩子,并输入了每个孩子的年龄,随后改变主意说她有 2 个孩子,我们不希望看到这 3 个已输入值的总和,因为在我们的例子中第三个孩子已经“不适用”了:

每个独立的表达式都以棕褐色背景进行颜色标记。如您所见,这里有三个独立的表达式。最后一个包含一条消息,仅当受访者有多于一个孩子时才会显示。

下面是该调查实际运行时的截图。
首次访问该页面时,您会看到如下内容。请注意,它显示的是“You have 0 children”,而不是“You have 0 child”。

如果我将孩子数量的值改为 1,即使仍在同一页面上,显示内容也会立即变为如下所示:

现在请注意语法是正确的:“You have 1 child”。
现在我将孩子数量的值改为 3,显示内容会立即变为如下所示。
请注意,您现在可以在底部看到条件消息:“The sum of ages of your first 3 kids is 0.”。
现在我为我虚构的孩子们输入年龄,得到如下显示,其中汇总了他们的年龄:

同样,在我输入数值时,分数和显示内容会立即更新,因此您可以利用这一点来显示评估分数的累计总和。
现在,我将孩子数量的值改为 2。显示内容变为如下所示:

请注意,虽然我为第三个孩子输入了 5.5 这个值,但报告现在只汇总前两个孩子的值。
原因是第 3 个值现在已不相关,而不相关的值会被 EM 主动忽略。
如果我把孩子数量改回 3,就会再次看到我输入的 5.5。因此,我在该页面上输入的任何信息都不会丢失。
但是,如果我导航到下一页或上一页,所有不相关的值在会话和数据库中都将被置为 NULL。因此,如果我保持值为 2,转到下一页,然后再返回并声明我实际上有 3 个孩子,我将不会再看到 5.5 这个年龄。
输入数据并在同一页面上查看动态变化的输入内容报告
本示例介绍了 LimeSurvey 中的定制(Tailoring)过程。
要下载此示例,请点击以下链接:动态变化调查示例。
页面最初的样子如下。您只会看到询问您居住在哪个城市的问题:

当您开始输入答案时,定制过程也随之开始:

当您输入答案时,页面底部的表格会随之更新,显示您的回复的回复编号和值。

常见调试示例
嵌套 if() 语句(条件逻辑)
EM 支持函数 "if(test,do_if_true,do_if_false)",以便您执行条件逻辑或定制。该函数可以嵌套使用,等效于 "if { } else if { } else { }"。如果括号不匹配(例如缺少右括号)或多出右括号,EM 会提示您。在编写较长的嵌套 if 语句时,请尝试数一数括号的数量,保存后检查是否存在语法错误,如有错误请予以修正。下面让我们一起来看这个示例。
下面使用的问题组可从此处获取:定制调查示例.lsg
首先,在未输入任何内容时,您只会看到 "你好。"

如果您输入姓名,则会显示 "你好 {name}。"

如果您输入年龄,将根据您是否为学龄前儿童得到定制的消息:

学龄儿童、青少年或成年人。下面是一位想要匿名的青少年:

这是该问题组的逻辑文件。如您所见,在 "if-based" 问题中,有基于人员年龄的嵌套 if 语句。

当您最初编辑此问题时,很可能在某个时候会出现括号数量错误。如果括号过少,会出现以下情况:

如果您将鼠标悬停在被红框包围的 "if" 一词上,会显示 "Parentheses not balanced"(括号不匹配)。在本例中,"already an adult!" 之后应有四个右括号,但只有三个。
另一方面,如果多出一个右括号,它会被红框包围,如下所示:

实际编辑该问题时,问题如下所示:

