表達式管理器
From LimeSurvey Manual
快速入門教程
綜述
在自定義調查時,你通常需要一種方法來指定以下內容:
- 導航/分支 - 根據主題答案改變問題的順序
- 裁剪(Tailoring)/管道(Piping) - 如何表達問題(例如提及先前的答案,或根據你的主題的數量或性別來結合句子),或如何生成自定義報告(如評估分數或量身定製的建議)。
- 驗證 - 確保答案通過某些條件,如最小值和最大值,或匹配輸入模式
表達式管理器(EM)提供了一種直觀的方法來指定每個功能的邏輯。即使你正在調用函數,幾乎任何你可以寫成標準數學方程的東西都是有效的表達式。 EM目前提供對70種函數的訪問,並且可以輕鬆擴展以支持更多函數。它還允許你使用人類可讀的變量名稱(而不是SGQA名稱)訪問變量。
以下部分顯示了使用表達式管理器的主要位置
相關性(控制導航/分支)
一些調查使用「跳轉邏輯(Goto Logic)」,這樣如果你用選項C回答問題1,那麼就會跳到問題5。這種方法非常有限,因為很難驗證,並且當你必須對問題進行重新排序時容易中斷。 表達式管理器(EM)使用布爾相關性方程來指定問題可能有效的所有條件。如果問題是相關的,則顯示問題,否則它不適用,並且將空值NULL存儲在資料庫中。這類似於可以通過條件編輯器完成的操作,但表達式管理器可以讓你輕鬆指定更複雜和更強大的準則(並允許你使用變量名而不是SGQA命名)。
此圖像顯示了一種審查調查的相關性邏輯的方法。它計算體重指數(BMI)。關聯方程式在變量名稱後面的方括號中顯示(以綠色顯示)。因此,weight,weight_units,height和height_units的相關性都是1,這意味著總是會問這些問題。然而,BMI的相關性是{!is_empty(height) and !is_empty(weight)},這意味著只有當受試者輸入身高和體重的值時才會計算BMI(從而避免除以零出錯的風險)。此外,僅當主題回答所有四個主要問題(身高,身高,體重,體重,體重_單位)時,才會顯示報告問題。
相關性在以下位置顯示和編輯:
查看/編輯問題級別相關性
該等式計算體重指數(BMI)。只詢問該人是否第一次輸入他們的身高和體重。
這是BMI問題的編輯屏幕。
請注意,輸入相關性方程時不要使用花括號。
查看/編輯組級相關性
這是一次簡單的人口普查。第一頁詢問有多少人和你住在一起並將其存儲在「cohabs」變量中。只有當你有多個同居者時才會顯示此頁面(因此會顯示第二個與你同居的人),並且僅顯示你是否指定了第一人與你的關係(p1_rel)。
如你所見,該組還具有問題級別的相關性標準,這樣每個問題只有在你回答之前的問題後才會出現(例如{!is_empty(p1_sex)})。 表達式管理器結合了群組和問題級別的相關性。僅詢問組中的問題是否與整個組相關。然後,僅詢問組內相關的問題子集。
以下是用於編輯該問題的組級相關性的屏幕:
請注意,輸入相關性方程時不要使用花括號。
裁剪(Tailoring)/管道(Piping)
表達式管理器可讓你輕鬆地對問題進行簡單而複雜的條件定製。有時你只需要簡單的替換,比如說,「您購買了 [ 產品]。您最喜歡它的是什麼?「。有時你需要條件替換,比如」 [ 名字] [ 先生/女士] ,您願意完成我們的調查嗎?「。在這種情況下,你想根據個人的性別使用先生或女士。其他時候你需要更複雜的替代(例如基於數學計算)。表達式管理器支持這些類型的裁剪/管道。
條件方程式
身體質量指數示例顯示了計算人的BMI的能力,即使讓他們以公制或非公制單位輸入他們的身高和體重。
這裡weight_kg是{if(weight_units == 'kg', weight, weight * .453592)}。這個if()函數意味著如果受試者使用公斤輸入重量,則使用該值,否則將輸入的值(以磅為單位)乘以.453592將其轉換為公斤。 height_m變量使用類似的方法計算人的身高(以米為單位),即使他以英寸為單位輸入身高。
BMI的權重計算公式為{weight_kg / (height_m * height_m)}。
最後,該報告有條不紊地裁剪了主題的信息,告訴對方他輸入了什麼。 (「您的身高為2米,體重為70公斤。」)
儘管上圖中沒有很好地顯示,但weight_status使用嵌套的if()語句將人分類為體重不足至嚴重肥胖。你可以在問卷邏輯視圖(Show Logic View)中看到它的等式
在這個問題的編輯窗口中,你可以看到兩件事:
- 裁剪(Tailoring)必須用花括號包圍表達式
- 如果要使嵌套的條件邏輯更易於閱讀, 則表達式可以跨越多行。
定製的(Tailored)問題,答案和報告
此示例顯示BMI報告。
這是同一問題的編輯窗口。
如你所見,花括號中的任何內容都被視為表達式,因此在前面的圖像中以語法突出顯示(顏色編碼)。如果你有任何拼寫錯誤(例如拼寫錯誤或未定義的變量名稱或函數),表達式管理器會顯示錯誤,例如,顯示height_unit是未定義的變量名稱(實際上是height_units),而rnd()是未定義的函數(正確的函數名稱是round())。在這兩種情況下,錯誤都被紅色框包圍,以便更容易發現並修復它們。
你還可以看到,你可以快速創建複雜的報告,例如輸入值表或定製建議。
請記住,所有裁剪(tailoring)都必須包含帶有花括號的表達式,以便LimeSurvey知道問題的哪些部分是自由文本,哪些部分應該通過表達式管理器進行解析。
驗證
表達式管理器控制大多數高級問題選項的工作方式。這些控制如最小/最大答案數;最小/最大個體值;最小/最大總和值;並檢查輸入的值是否與指定的字符串模式匹配。你可以像往常一樣繼續輸入這些高級問題選項。但是,現在其中一個欄位中的任何值都被視為表達式,因此你可以使用與其他問題具有複雜條件關係的最小/最大條件。
在所有這些情況下,由於高級問題選項始終被視為表達式,因此在指定它時不使用花括號。
調查示例頁面顯示了許多使用表達式進行驗證的工作示例。
簡介
LimeSurvey使用新的表達式管理器(EM)模塊,這將使LimeSurvey支持更複雜的分支,評估,驗證和定製。它將取代LimeSurvey在後端如何管理替換,條件和評估。它還可以大大加快處理速度,因為它消除了大多數運行時的資料庫讀取。 EM由Thomas White博士(TMSWhite)開發。
此Wiki頁面是Expression Manager語法和功能的權威參考。
關鍵定義
- 表達式(Expression):任何被花括號包圍的東西
- 只要在開括號之後或閉合花括號之前沒有空格
- 表達式的內容由表達式管理器(EM)評估,因此它們可以包含數學公式,函數以及複雜的字符串和日期處理。
- 裁剪(Tailoring):有時稱為「管道(piping)」,這是過程有條件地修改文本
- 你可以訪問所有「替換欄位」,參與者數據和響應數據。
- 你還可以更輕鬆地訪問問題,答案及其屬性。
- 關聯(Relevance)方程式:一個控制問題可見性的新問題屬性
- 如果存在相關方程(relevance equation),那麼僅在相關性評估為真時才顯示問題。
- 在內部,所有array_filter和array_filter_exclude命令成為子問題級別的相關性
- 方程式(Equation)問題類型:一種新的問題類型,可以將計算或報告保存到資料庫中
- 它就像一個樣板文件(Boilerplate)問題,但即使你設置「始終隱藏此問題」,其內容也會保存到資料庫中
- 問題代碼:這是EM的首選變量名
- 這可以是一個描述性名稱, 指示問題的目的, 使其更容易閱讀複雜的邏輯
- 有效的問題代碼不應該以數字開頭,所以當使用問題代碼為你的問題編號時,只需使用「q1」 「,或」q1a「或」g1q2「。
- 如果你將數據導出到SPSS或R,那麼這就是當前變量名稱,因此如果你進行統計分析,你可能已經將此變為唯一。
我必須使用表達式管理器(EM)?
簡單來說是 "否" (但也是 "是")。
EM完全向後兼容現有的調查。因此,如果你樂意在低於1.91+版本的LimeSurvey中使用條件和評估,你可以繼續這樣做。
但是,EM完全取代了LimeSurvey內部處理條件的方式。雖然你仍然可以使用條件編輯器來創建和管理條件,但LimeSurvey 1.92會將這些條件轉換為等效的相關方程式。作為升級的一部分,LimeSurvey 1.92會將所有現有條件自動轉換為相關方程式。
這應該可以為你提供兩全其美的效果 - 你可以像以前一樣繼續使用LimeSurvey,但會看到相關等式,因此你可以在需要時直接逐漸遷移到相關方程式。
我可以混合使用條件和相關方程嗎?
是。你可以將條件編輯器用於某些問題,將相關方程編輯器用於其他問題。保存問題時,條件會自動轉換為相關方程。
注意,我們假設如果你正在使用條件編輯器,那麼你希望這些條件覆蓋任何手動輸入的相關性方程式。因此,如果你有現有條件並想要手動編輯相關性,請先刪除該問題的條件。具體來說,將生成的相關性方程式複製到文本編輯器,使用「條件」菜單刪除該問題的所有條件(這也將刪除相關方程),然後編輯問題並將生成的相關方程式從文本編輯器粘貼回該問題的相關性欄位(並保存問題)。如果有足夠的需求刪除條件而不刪除生成的相關方程式,我們可以添加批量轉換過程。
如何在條件和相關性之間進行選擇?
以下是每種方式的優缺點列表:
方式 | 優點 | 缺點 |
---|---|---|
條件 | 1.用於創建簡單條件的精美GUI 2.GUI有良好的文檔,並且便於理解 ,這一切都得益於支持團隊 |
1.僅支持簡單比較,並且不支持AND / OR條件 2.級聯條件不規律地工作 3.緩慢 - 資料庫密集,因此會減慢長期調查 4.一些人報告了重裝條件的問題 5.當有數十,數百或數千個問題時,GUI不能很好地擴展 6.由於必須使用SGQA名稱,因此轉換基於紙張的調查可能會很慢 7.經常需要程式設計師自定義複雜分支所需的邏輯 |
相關性 | 1.支持非常複雜的邏輯,包括80多個函數和數學/字符串運算符 2.完美支持級聯邏輯 3.快速 - 無需額外的資料庫調用,因此支持1000多個問題調查 4.重新加載邏輯沒有問題,因為不需要SGQA代碼 5.語法突出顯示縮放到1000多個問題調查 6.方便快捷地用於希望計算機化現有紙質調查的團體。 7.輕鬆支持半結構化訪談和流行病學調查,無需程式設計師 |
1.沒有簡單條件的GUI - 而是使用語法高亮 2.新的,所以支持團隊尚未掌握EM。 |
最重要的是,如果你對LimeSurvey 1.91+的工作方式感到滿意,則沒有理由改變你的工作。
使用EM有哪些其他好處?
以下是你可能想要使用EM的其他一些原因。
- 計算(Calculations) - 你可以創建任何你能想到的計算:
- 你可以訪問所有常見的數學運算符和函數
- 你可以訪問70多個數學、日期和字符串處理函數
- 如果用戶需要,開發人員可以很容易地添加新函數
- 將計算存儲到資料庫
- 你現在可以計算簡單和複雜的算式和/或量表分數,並將它們存儲在資料庫中而無需JavaScript。
- 你可以使用方程式(Equation)問題類型來完成此任務。
- 評估(Assessments)
- 你現在可以創建任何問題類型的評估或量表分數,而不僅僅是過去支持的子集
- 你可以使用裁剪在任何需要的地方顯示運行或總評估分數 - 即使在同一頁面上
- 你有更多控制權基於這些評估分數生成的報告
- 你可以在不需要JavaScript的情況下將評估分數存儲在資料庫中
- 你可以隱藏評估分數而不需要JavaScript或CSS
- 替換欄位(Replacement Fields)
- 你可以使用問題代碼而不是使用{INSERTANS:SGQA} - 這使它更容易閱讀並且驗證。
- 這也避免了編輯問題以改變SGQA代碼以使一切正常工作的常見需求。
- 裁剪(Tailoring) - 你可以根據其他值有條件地顯示文本
- 使用適當的一個主題的標題,如(例如「您好,史密斯[先生/女士]。」)
- 基於單數/複數時輸出格式正確的句子:(例如」你有1個孩子「與」你有2個孩子「)
- 根據主題的性別和多數來調整動詞的形式和名詞變格。
- 新變量屬性 - 你可以訪問以下內容進行剪裁:
- (無後綴) - qcode.code的別名
- .code - 相關問題的選定響應代碼(如果它是相關的,否則為空白),或文本值(如果它不是編碼問題)
- .NAOK - 與.code相同,但可以是計算或列表的一部分即使不相關
- .value - 問題的評估值(如果它是相關的,否則為空白),或文本值,如果它不是編碼問題
- .valueNAOK - 與.value相同,但是即使不相關也可以成為計算或列表的一部分
- .show - 顯示給用戶的答案(這是{INSERTANS:xxx}所做的)
- .qid - 問題ID
- .gid - 組ID
- .sgqa - 問題的SGQA值
- .jsName - 問題的正確javascript變量名,無論是否在此頁面上定義
- .qseq - 問題序列(從0開始)
- .gseq - 組序列(從0開始)
- .mandatory - 問題是否是強制性的(是/否)
- .question - 問題的文本
- .relevance - 該問題的相關性方程式
- .gllevance - 該組的相關性方程式
- .intelationsationStatus - 當前問題是否相關(如果為真則為1,如果為假則為0)
- .type - 問題類型(一個字符代碼)
- 動態頁面更改
- 所有相關性,計算和裁剪在頁面上動態工作 - 因此值的更改會立即更新頁面
- 所以,你有問題根據它們是否相關而動態顯示/消失
- 問題也是根據頁面上的響應動態定製的,因此你可以看到運行總計,量身定製的句子和自定義報告。
- 新的數據輸入屏幕
- 除了使用當前的數據錄入系統外,你還可以使用Survey-All-In-One。
- 這支持頁面相關性和剪裁,因此數據錄入員可以快速完成選項卡通過,他們只需要輸入相關的回覆
- 如果你的數據輸入人員需要查看剪裁,這也是動態的,這可能是至關重要的。
- 消除了對大多數自定義JavaScript的需求
- EM很容易支持複雜的計算,評分,剪裁和條件邏輯。
- 有些東西仍然需要JavaScript(比如自定義布局和有條件隱藏的問題子元素),但是你的JavaScript可以使用EM函數,這樣你可以通過Qcode而不是SGQA訪問問題,並訪問上面列出的任何問題屬性。
EM啟用了哪些其他有用的新功能?
無論你是繼續使用條件編輯器還是手動構建相關方程式,你都可以獲得以下額外好處:
- 你可以創建更複雜的驗證標準
- 所有高級問題屬性(如max_answers,min_num_value_n, max_num_value)可以使用表達式。因此,你可以根據先前的響應輕鬆調整最小/最大標準,即使它們位於同一頁面上。
- EM還處理所有基於正則表達式的驗證,因此你可以強大地組合preg和equation-基於問題屬性。
- 方便地重新排序(或刪除)問題和組
- 在版本1.92之前,如果LimeSurvey認為重新排序可能會破壞被使用的條件,則無法重新排序問題或組。同樣,如果有任何其他問題依賴於它們,則無法刪除問題。
- 使用EM的語法突出顯示,很容易看到並驗證你是否在聲明之前嘗試使用問題。因此,我們現在允許你隨時重新排序或刪除問題和群組。 EM將更新所有語法突出顯示以顯示潛在錯誤。
- 重新排序問題視圖已得到增強,以幫助進行此類審核。它現在顯示問題的相關性方程和剪裁,因此你可以立即查看是否有任何變量變為粉紅色(意味著它們在被聲明之前使用)。
- 問題/組導航索引始終可用且準確
- 在版本1.92之前,如果有複雜的條件,這些索引不可用
- 使用EM,我們可以保證它們是準確的。
- 主題甚至可以跳回到先前的問題,更改答案然後向前跳(或提交)
- 當向前跳時,EM將重新驗證所有介入的問題/組。
- 如果任何問題變得無關緊要,它們將在資料庫中為空因此,你的數據在內部是一致的
- 如果任何問題變得相關或新的失敗強制或驗證規則,EM將停在該頁面上並強制用戶在跳到最終目的地之前回答這些問題。
- 自動將條件轉換為相關性
- 升級資料庫時,所有現有的調查具有條件的條件將為它們生成關聯方程式
- 每當你導入調查時,將根據需要創建關聯方程式
- 無論何時添加,刪除或修改條件,EM都將生成相應的關聯方程。
- 方便的語法突出顯示
- 當EM顯示相關性方程式時,它將顯示Qcode,即使你輸入了SGQA代碼,因為我們認為這將更容易閱讀。
- 全部變量採用顏色編碼,以顯示它們是在當前問題之前還是之後(或當前組之前或之後)聲明的。這使你可以快速檢測並修復在聲明變量之前嘗試使用變量進行相關性(包括array_filter),定製或驗證方程式的情況。
- 此外,如果將滑鼠懸停在顏色編碼變量上,你將看到有關該問題的最重要的元數據。這包括組序列#,問題序列#,Qcode,問題文本和所有可用答案選項(如果它是具有枚舉答案選項的問題類型)。
- 答案選項列表使用此語法: 'answers':{key:val, ... }.。
- key的語法為'scale~code''scale是答案量表(例如,對於雙比例),代碼是答案代碼。
- val的語法'value~shown'其中value是評估值(如果使用評估,否則代碼)(例如Qcode.value),shown是主題看到的顯示值(例如Qcode.shown)
- 這意味著許多調查可以使用計算而無需評估模式。如果你有枚舉唯一,非小數和非負數的答案選項,你可以簡單地對Qcode.code值進行計算。
- 簡單評估整個調查邏輯和內容
- 有一個新的顯示問卷邏輯(Show Survey Logic)功能,可讓你在一個頁面上查看有關調查(或組或問題)的所有內容。
- 顯示所選範圍的組、問題、子問題和答案級別詳細信息(調查與群組與問題)
- 它還顯示相關性,子問題級別相關性(對於array_filter和array_filter_exclude),以及生成的驗證方程式(對於preg和任何驗證規則,如最小值/最大值和數量)所有非空白問題屬性。
- 所有內容都是語法突出顯示的,這樣你就可以看到潛在的語法錯誤(比如不平衡的括號或在聲明它們之前使用變量)
- 語法 - 高亮顯示支持快速導航和編輯調查。
- 如果你點擊一個變量名,它會打開一個瀏覽器窗口(或標籤),顯示該問題,並允許你編輯它。
- 如果你單擊組名稱,它將打開一個瀏覽器窗口(或選項卡),顯示組重新排序視圖,以便你可以輕鬆移動問題。
- 所有問題屬性也都是語法突出顯示。這使你可以在高級問題選項中設置和查看表達式(例如基於表達式的最大/最小數量/值的總和)
- EM作者使用類似的視圖(更清潔一點)讓他的合作流行病學家和機構審核委員會在高度分支和量身定製的結構化訪談中驗證並授權調查數千個問題
入門
開始使用EM的最佳方法是:
- 從http://www.limesurvey.org/en/download安裝最新的穩定版本
- 導入並探索示例調查。
- 探索用例和HowTos和分步示例。
- 瀏覽EM文檔(本頁)
- 檢查內置的EM測試套件
- 從任何調查,在工具下,選擇EM選項
- 可用功能列出70多種函數和語法
- 單元測試隔離表達式
- 顯示了使用所有EM函數和運算符的示例,以及PHP和JavaScript結果
- 注意,很少有函數在PHP和JavaScript版本中生成不同的結果,因此該頁面允許你相應地計劃你的EM邏輯。
表達式管理器擴展/替換的功能是什麼? (LimeSurvey <= 1.91 +)
條件 => 相關性
條件控制哪些問題可見。一般語法是SGQA operator Value,比如111X2X3 ==「Y」。條件可以進行AND運算或OR運算,但混合AND和OR很困難。條件本身存儲在一個單獨的表中,LimeSurvey的大部分代碼專門用於管理條件。由於廣泛的資料庫訪問,處理大量條件可能會導致顯著的性能問題。此外,一旦你將條件分配給問題或組,你通常不被允許重新排序或刪除它們。
Assessments =>方程式和微裁剪
評估使用戶可以從一組問題中創建比例分數。但是,它們無法在當前頁面上動態更改,並且它們的值未存儲到資料庫中。
替換=>微裁剪
用戶可以根據之前的響應定製一些消息和問題。例如,一個問題可能是{TOKEN:FIRSTNAME},而{INSERTANS:111X3X4}是你最喜歡的運動。然而,不可能做有條件的剪裁(比如說「先生」或「太太」取決於人的性別),或者沒有花哨的JavaScript的共軛動詞或拒絕名詞。作者可以實施似乎可以定製問題的調查,但是每個排列需要單獨的問題,並且需要複雜的條件來決定要顯示哪些問題。
驗證
可以使用正則表達式或最小值/最大值驗證問題,或者讓SGQA響應作為最小值或最大值。但是,如果沒有異常複雜的JavaScript,驗證不能基於其他變量的計算。
方程式
沒有異常複雜的JavaScript,方程式將不被支持。
方程式問題類型
沒有異常複雜的JavaScript,方程式無法保存到資料庫中(例如評估的最終得分)。
表達式管理器將如何替換/擴展該功能?
表達式管理器是LimeSurvey中的一個新核心模塊,它使得支持過去需要自定義JavaScript的複雜功能類型變得更加容易。它也取代了LimeSurvey目前管理條件和評估的方式。
引用表達式管理器(EM)時的新術語
EM以下列術語「思考」其功能:
- 基於相關性的分支 - 如果問題是相關的,則問它,否則不要(例如使其隱形,並標記它)在資料庫中為NULL)。所有問題類型以及每個組都有一個新的相關性欄位(因此你可以將一組條件應用於整個組,而無需將相同條件複製到每個問題,和/或組合組和問題級條件邏輯)。
- '剪裁 - 一旦你知道應該問哪些問題,剪裁(有時稱為管道)指定如何詢問問題。這樣,你不僅可以支持簡單的替換(如{TOKEN:FIRSTNAME}),還可以根據你的主題的性別或數量來支持動詞的結合和名詞的下降。它還允許你根據他們是否回答(或他們如何回答)其他問題來更改您傳遞給主題的信息。
- 方程式 - EM添加一個名為Equation的新問題類型,用於存儲結果一個表達。即使你在頁面上隱藏它們,也會計算這些方程式結果並將其寫入資料庫。因此,它們可用於隱藏評分計算,基於複雜方程的導航,評估以及應在資料庫中輕鬆獲得的報告。
相關性和級聯相關性
每個問題類型現在都有一個相關性選項,用於控制是否顯示問題。 EM按照它們應該出現在調查中的順序處理每個相關方程。如果表達式為真(或缺失 - 支持舊版調查),則會顯示問題。如果它不相關,則將隱藏該問題,並且該值將在資料庫中為NULL。如果組中沒有相關問題,則將跳過整個組。
此外,如果表達式中的任何變量不相關,則表達式始終求值為false。這啟用了級聯相關性,因此你不必為每個問題編寫非常長的相關性方程式。
假設你有Q1-Q5的5個問題,並且你只想在Q1被回答時顯示Q2,如果Q2被回答則顯示Q3等。相關性等式可能是:
問題代碼 | 相關性 | 問題 |
---|---|---|
Q1 | 1 | 你叫什麼名字? |
Q2 | Q1 | {Q1},你多大了? |
Q3 | Q2 | 所以,你是{Q2}歲。你結婚了嗎? |
Q4 | Q3 ==「Y」 | {Q1},你結婚多久了? |
Q5 | Q4 | 你有幾個孩子,{Q1}? |
相關性計算也適用於JavaScript - 因此你可以將所有上述問題放在一個頁面上,它仍然可以按預期工作。實際上,EM完全取代了EM處理調查與組與一次調查問卷調查格式的方式。他們現在都使用完全相同的導航引擎,因此無論調查風格如何,它們的工作方式相同。
只要你在同一頁面上,你輸入的任何數據仍然會存在,只是隱藏了。因此,如果你輸入一些信息,然後選擇一個使它們無關緊要的選項,然後再次使它們相關,你的答案仍然可用。但是,只要你移動到其他頁面,所有不相關的響應都將丟失到數據集的完整性。
組級相關性
表達式管理器還支持組級相關性。這樣可以更輕鬆地實現循環。假設你要收集有關多達10個實體(此類產品或家庭中的人)的信息,你首先要確定需要跟進的實體數量(例如詢問有多少人居住在家中,或讓人們檢查從長長的名單中他們喜歡哪些產品)。在知道有多少實體需要跟進後,你可以使用組級別相關性,例如{count> = 1},{count> = 2},... {count> = 10},對於以下10組中的每一組都是如此問題。在每個組中,你可以使用問題級條件邏輯(例如針對每個主題的性別或年齡特定的後續問題)。將問題和組級相關性方程式進行AND運算以確定應顯示哪個。
裁剪(Tailoring)/管道(Piping)
花括號內的任何內容現在都被視為表達式(下面有一個例外)。表達式適用於所有LimeReplacementFields,所有變量(通過幾個別名),所有典型的方程式運算符(數學,邏輯和比較),以及許多函數(甚至可以在客戶端動態工作)。
使用這些方程式,您可以執行以下操作:
- 根據先前的響應, 有條件地向響應者顯示量身定製的消息
- 創建評估並根據這些結果顯示評估結果 (或有條件地分支或顯示消息), 而無需使用評估模塊本身
- 在問題、答案和報告中結合動詞和拒絕名詞。
- 在調查結束時顯示「顯示您的答案」頁面之前的答覆摘要
方程式
有一種叫做方程式的新問題類型。它就像一個Boilerplate問題,除了它存儲資料庫中顯示的內容的值。因此,如果方程問題文本包含評估計算,則該值將存儲在資料庫中的變量中,該變量可以在公共或私有統計信息中顯示。
這解決了在資料庫中存儲評估分數的常見請求
語法
花括號中包含的任何內容現在都被視為一個表達式(有一個例外:必須沒有前導或尾隨空格 - 這是確保表達式管理器不會嘗試處理嵌入式JavaScript所必需的)。
注意,表達式可以跨越多行,只要在開始大括號之後或結束大括號之前沒有空格。這對於嵌套的if()語句特別有用:
{if(is_empty(PFTotals),
'',
if(PFTotals >= -5 && PFTotals <= -4,
'Very Soft',
if(PFTotals >= -3 && PFTotals <= -2,
'Soft',
if(PFTotals == -1,
'Somewhat Soft',
if(PFTotals == 0,
'Moderate',
if(PFTotals == 1,
'Somewhat Hard',
if(PFTotals >= 2 && PFTotals <= 3,
'Hard',
if(PFTotals >= 4 && PFTotals <= 5,
'Very Hard',
''
)
)
)
)
)
)
)
)}
- 所有標準數學運算符(例如+, - ,*,/,!)
- 所有標準比較運算符(例如<,<=,==,!=,>,> =,加上這些等價物: lt,le,eq,ne,gt,ge)
- 圓括號(所以你可以將子表達式分組)
- 條件運算符(例如&&,| |和這些等價物:和,或者)
- 單引號和雙引號字符串(每個字符串可以用其他引號類型嵌入字符串)
- 逗號運算符(因此可以有一個表達式列表,只返回最終結果)
- 賦值運算符(=)
- 預定義變量(用於指代問題,問題屬性和響應) - 例如所有SGQA代碼
- 預定義函數(已經有70多個,並且很容易添加更多)
運算符
EM語法遵循正常的運算符優先級:
等級 | 運算符 | 說明 |
---|---|---|
1 | () | 用於分組或調用函數的括號 |
2 | ! - + | 一元運算符:邏輯「非」,一元求反,一元加 |
3 | * / | 乘,除 |
4 | + - | 加 ,減 |
5 | < <= > >= lt le gt ge | 相對比較 |
6 | == != eq ne | 相等比較 |
7 | and | 邏輯「和」 |
8 | or | 邏輯「或」 |
9 | = | 賦值 |
10 | , | 逗號 |
Warning with plus operator (+)
注意,為了JavaScript和PHP之間的一致性,如果兩個操作數都是數字,則加號運算符(+)會添加,但如果兩個部分都是非數字字符串,則會進行連接。但是,我們建議使用join()函數進行連接,因為這會使你的意圖更加清晰,並且如果你期望字符串而不是數字(或反之亦然),則可以避免意外結果。
Warning with mismatch between number and string and alphabetic comparison
When you want to compare value with relative or equality comparisons, pay attention to type mismatch. Value entered by user or answer code selected can be used as number if it's clearly a number.
If you surround one of the values with "
it will force the comparison as text (alphabetic compare). If you want to compare numerically, never surround the number with quotation marks, "
.
For example Q0.NAOK > "50"
is true if Q0.NAOK is a numeric question with 9 as value. This is because the operator >
will assume it's alphabetical compare and not numerical.
To be sure to compare integer value, you can use intval(Q0.NAOK) > 50
, just remember if Q0.NAOK is not a number (empty or a string), then intval(Q0.NAOK) == 0. To compare string value ("A" < "B") use strcmp directly : strcmp(Q0.NAOK,"B")
or strcmp(Q0.NAOK,"A5")
.
關於使用賦值運算符(=)的注意事項
注意,除非絕對必要,否則應避免使用賦值運算符,因為它們可能會導致意外的副作用。例如,如果你更改先前響應的值,則不會重新計算該問題與當前問題之間的級聯相關性和驗證邏輯,因此你最終可能會得到內部不一致的數據(例如,問題仍然可以得到解答但應該具有已被NULL,或者被跳過但應該已經回答的問題)。通常,如果要為變量賦值,則應創建方程式問題類型,並使用表達式設置其值。然而,人們真的需要這個運算符,但是我們很少有人能夠使用它。
為了幫助提醒你這個操作符,它在語法方程中以紅色字體顯示(這樣你就不會將它與「==」混淆)
使用賦值運算符
你可能想要使用賦值的主要原因是:
- 你需要通過等式設置不接受默認值的問題的默認值(例如列表單選,用戶界面允許你選擇一個答案選項,但不允許你輸入等式)。但是,要小心,因為LimeSurvey將無法驗證你的等式是否為該問題生成了允許的答案之一。
- 你需要根據以後的響應強制更改對先前問題的響應
等等……
您可以使用所有表達式管理器系統來實現此目的。為此目的,最好使用方程式問題類型。
一些例子:
- 用小寫設置答案的短文本問題:
{QCODE=strtolower(QCODE.NAOK)}
- 在調查開始時設置數組問題類型的默認答案:
{Q1_SQ1=(is_empty(Q1_SQ1.NAOK),"A99",Q1_SQ1.NAOK)}
- 在調查開始時設置數組文本問題類型的默認答案:
{Q1_SQY1_SQX1 = (is_empty(Q1_SQY1_SQX1.NAOK),"Inserted answer", Q1_SQY1_SQX1.NAOK)}
- 用條件設置答案:
{QCODE=if(YesNo="Y","A1","")}
XSS安全
使用XSS啟用時,不能使用某些表達式管理器系統:
- 在表達式中啟動HTML標記但以另一個表達式結束
- 在URL中使用複雜表達式。
示例和解決方法
{if( 1 ,"<strong>","")}information{if( 1 ,"</strong>","")}
is broken with XSS security, here you can use{if(1,"<strong>information</strong>","information")}
<a href="/script.php?value={if(QCODE == "Y","yes","no")}">next</a>
, here you can use an equation question because using a complete question code is OK :<a href="/script.php?value={EQUATION.NAOK}">next</a>
訪問變量
表達式管理器提供對我們可能需要的任何變量的只讀訪問權限。為了向後兼容,它提供對以下內容的訪問:
- TOKEN:xxx - TOKEN的值(例如TOKEN:FIRSTNAME,TOKEN:ATTRIBUTE_5)(僅用於非匿名調查)。
- INSERTANS:SGQA - 答案的顯示值(例如「是」)。對於Expression Manager,它與使用{QCODE.shown}相同。
- 所有{XXX} values used by templates。
- 在問題文本中,你可以使用{QID}替換由問題id和{SGQ}取代SGQA的問題
此外,表達式管理器允許你通過問題代碼(資料庫中問題表中的「標題」列)引用變量。這也是將數據導出到SPSS,R或SAS時使用的變量標籤。例如,如果你對姓名,年齡和性別有疑問,可以將這些變量稱為「姓名」,「年齡」和「性別」,而不是「12345X13X22」,「12345X13X23」 '和12345X13X24。這使得每個人都可以更容易地閱讀和驗證邏輯,並且可以在不必跟蹤組或問題數字的情況下隨機調整問題。
重要:引用前幾頁或問題中出現的變量是安全的。
此外,表達式管理器允許你訪問問題的許多屬性:
語法 | 含義 | 示例 | 示例結果 |
---|---|---|---|
Qcode | Qcode.code的別名 | {implode(',',name,gender)} | 'Tom','M' |
Qcode.code | 選擇的問題響應代碼是否相關(否則為空白),或文本值(如果不是)編碼問題 | {implode(',',name.code,gender.code)} | 'Tom','M' |
Qcode.NAOK | 與Qcode相同 - 請參閱討論NAOK | {gender.NAOK} | 'M' |
Qcode.value | 問題的評估值是否相關(否則為空白),如果不是,則為文本值編碼問題 | {gender.value} | '1' |
Qcode.valueNAOK | 問題的評估值是否相關(否則為空白),如果不是,則為文本值編碼問題 | {gender.valueNAOK} | '1' |
Qcode.shown | 問題的顯示值 | {implode(',',name.shown,gender.shown)} | 'Tom','Male' |
Qcode.question | 問題的文字 | {gender.question} | 'What is your gender?' |
Qcode.mandatory | 是否有問題是強制性的(是/否) | {gender.mandatory} | 'N' |
Qcode.qid | 內部問題編號(不是序號) | {gender.qid} | 337 |
Qcode.type | 問題類型 | {gender.type} | 'G' |
Qcode.jsName | 問題的正確javascript名稱,無論是否在此頁面上聲明 | {gender.jsName} | 'java1827X3X337' |
Qcode.gid | the internal 內部組號(不是序號) | {gender.gid} | 3 |
Qcode.qseq | 問題的序號,從0開始 | {gender.qseq} | 5 |
Qcode.gseq | 組的序號,從0開始 | {gender.gseq} | 1 |
Qcode.relevanceStatus | 問題當前是否相關(0或1) | {gender.relevanceStatus} | 1 |
Qcode.relevance | 問題級相關方程式 | {gender.relevance} | '!is_empty(name)' |
Qcode.grelevance | 組級相關性方程式 | {gender.grelevance} | 'num_children >= 5' |
Qcode.sgqa | 此問題的SGQA值 | {gender.sgqa} | '1827X3X337' |
HTML編輯器問題
如果你使用HTML編輯器,則某些字符將被HTML實體替換。
- & by &
- < by <
- > by >
如果你使用HTML編輯器,則需要使用:
- and for &
- lt for <
- le for <=
- gt for >
- ge for >=
Qcode變量命名
以下是如何按問題類型構造Qcode(並訪問某些屬性)的詳細信息。通常,Qcodes構造如下:
QuestionCode . '_' . SubQuestionID . '_' . ScaleId
對於評論和其他,問題代碼是QuestionCode_comment和QuestionCode_other
類型 | 說明 | 代碼 | 子問題 | 答案選項 | 比例 | 答案代碼 | 答案顯示 | 相關性 |
---|---|---|---|---|---|---|---|---|
5 | 5 Point Choice Radio-Buttons | Q1 | 1-5 | {Q1} | {Q1.shown} | {Q1==3} | ||
B | Array (10 Point Choice) Radio-Buttons | Q2 | L1-L6 | 1-10 | {Q2_L2} | {Q2_L2.shown} | {Q2_L2==7} | |
A | Array (5 Point Choice) Radio-Buttons | Q3 | 1-5 | 1-5 | {Q3_1} | {Q3_1.shown} | {Q3_1>=3} | |
1 | Array (Flexible Labels) Dual Scale | Q4 | sq1-sq5 | 0:a1-a3 | 1:b1-b3 | {Q4_sq1_0} | {Q4_sq1_1.shown} | {Q4_sq1_1=='b2'} |
H | Array (Flexible) - Column Format | Q5 | 1-5 | s,m,t | {Q5_1} | {Q5_1.shown} | {Q5_1=='s'} | |
F | Array (Flexible) - Row Format | Q6 | F1-F5 | 1-5 | {Q6_F3} | {Q6_F3.shown} | {Q6_F3==4} | |
E | Array (Increase/Same/Decrease) Radio-Buttons | Q7 | 1-7 | I,S,D | {Q7_4} | {Q7_4.shown} | {Q7_4=='D'} | |
: | Array (Multi Flexi) 1 To 10 | Q8 | ls1,todo,ls2 | min,max,avg | {Q8_ls1_max} | {Q8_ls2_avg.shown} | {Q8_ls2_min==7} | |
; | Array (Multi Flexi) Text | Q9 | hp,st,sw | 1st,2nd,3rd | {Q9_hp_3rd} | {Q9_hp_3rd.shown} | {Q9_hp_3rd=='Peter'} | |
C | Array (Yes/Uncertain/No) Radio-Buttons | Q10 | 1-5 | Y,N,U | {Q10_1} | {Q10_1.shown} | {Q10_3=='Y'} | |
X | Boilerplate Question | Q11 | {Q11.shown} | |||||
D | Date | Q12 | {Q12} | {Q12.shown} | ||||
* | Equation | Q13 | {Q13} | {Q13.shown} | {Q13>5} | |||
~124~ | File Upload (records number of files uploaded) | Q14 | {Q14} | {Q14>0} | ||||
G | Gender Drop-Down List | Q15 | M,F | {Q15} | {Q15.shown} | {Q15=='M'} | ||
U | Huge Free Text | Q16 | {Q16} | {Q16.shown} | {strlen(Q16)>100} | |||
I | Language Question | Q17 | {Q17} | {Q17.shown} | {Q17=='en'} | |||
! | List - Dropdown | Q18 | 1-5 | {Q18} | {Q18.shown} | {Q18==3} | ||
L | List Drop-Down/Radio-Button List | Q19 | A-Z | {Q19} | {Q19.shown} | {Q19=='X'} | ||
O | List With Comment Drop-Down/Radio-Button List + Textarea | Q20 | A-F | {Q20},{Q20comment} | {Q20.shown} | {Q20=='B'} | ||
T | Long Free Text | Q21 | {Q21} | {Q21.shown} | {strstr(Q21,'hello')>0} | |||
M | Multiple Choice Checkbox | Q22 | A-F, other | {Q22_E}, {Q22_other} | {Q22_E.shown}, {Q22_other.shown} | {Q22_E=='Y'} | ||
P | Multiple Choice With Comments Checkbox + Text | Q23 | A-F | {Q23_D}, {Q23_Dcomment} | {Q23_D.shown} | {!is_empty(Q23)} | ||
K | Multiple Numerical Question | Q24 | self,mom,dad | {Q24_self} | {Q24_self.shown} | {Q24_self>30} | ||
Q | Multiple Short Text | Q25 | A-F | {Q25_B} | {Q25_B.shown} | {substr(Q25_B,1,1)=='Q'} | ||
N | Numerical Question Type | Q26 | {Q26} | {Q26.shown} | {Q26 > 30} | |||
R | Ranking Style | Q27 | 1-4 | {Q27_1} | {Q27_1.shown} | {Q27_1==3} | ||
S | Short Free Text | Q28 | {Q28} | {Q28.shown} | {Q28=='mine'} | |||
Y | Yes/No Radio-Buttons | Q29 | {Q29} | {Q29.shown} | {Q29=='Y'} |
保留的'this','self'和'that'變量
通常,你希望評估問題的所有部分,例如計算已回答的子問題的數量,或總結得分。其他時候,你只想處理問題的某些行或列(例如獲取行或列的總和並將它們存儲在資料庫中)。這些保留的變量使該過程相對無痛。
'this'變量專門用於「整體問題驗證方程」和「子問題驗證方程」高級問題選項中。它擴展為這些問題中每個單元格的變量名稱。因此,如果要確保每個條目都大於3,則可以將「子問題驗證方程式」設置為(this> 3)。
'self'和'that'變量更強大,並且用作在處理方程之前擴展的宏。語法選擇是:
- self
- self.suffix
- self.sub-selector
- self.sub-selector.suffix
後綴是任何正常的qcode後綴(例如NAOK、value、shown)
子選擇器是以下之一:
- 注釋 - 只有作為注釋的子項(例如來自帶注釋的多項選擇和帶注釋的列表)
- 沒有注釋 - 只有不是注釋的子項
- sq_X - 其中X是行或列標識符。僅選擇與模式X匹配的子查詢。請注意,搜索是在完整的代碼標識符上完成的,然後sq_X匹配並包含子請求nX,X,Xn(例如,如果使用sq_1,則包含子參數a1,1a,1,11或001)。注意雙尺度問題類型,其中子問題代碼是QCODE_SQCODE_1和QCODE_SQCODE_1,以及排序問題類型,其中子問題代碼是QCODE_1,QCODE_2 ....
示例:
- 是否已回答問題的任何部分?{count(self.NAOK)>0}
- 這個問題的評估分數是多少? {sum(self.value)}
你還可以使用它們來獲取行和列總計。假設你有一組數字,其中包含AE行和第1-5列。
- 總計是多少? {sum(self.NAOK)}
- B行的總數是多少? {sum(self.sq_B.NAOK)}
- 第3列的總數是多少?{sum(self.sq_3.NAOK)}
'that'變量就像'self'變量,但是讓你引用其他問題。它的語法是:
- that.qname
- that.qname.suffix
- that.qname.sub-selector
- that.qname.sub-selector.suffix
qname是沒有任何子查詢擴展名的問題名稱。所以,假設您創建了一個問題'q1',那就是qname
示例:
- 是否已回答問題q1的任何部分? {count(that.q1.NAOK)>0}
- q2的評估分數是多少?{sum(that.q2.NAOK)}
- q3的總計是多少? {sum(that.q3.NAOK)}
- q4中C行的總數是多少? {sum(that.q4.sq_C.NAOK)}
- q4中第2列的總數是多少? {sum(that.q4.sq_2.NAOK)}
'self'和'that'變量可用於任何相關性、驗證或定製。
需要注意的是,當你使用顯示邏輯文件功能時,它將顯示'self'和'that'的擴展值。這使你可以看到將生成的實際等式,以便你(和表達式管理器)可以驗證變量是否存在。這可能看起來令人困惑,因為你可能會看到相當長的方程式。但是,如果你編輯問題,你將看到使用'self'和/或'that'的原始等式
另請注意,如果(a)要明確命名方程中使用的每個變量,或(b)使用沒有子參數的變量(例如單個響應問題),則不應使用這些變量。在這些情況下,為變量添加'that'前綴是過度的,並且存在獲得意外結果的風險。
NAOK的用法
NAOK -->「不適用」(NA)沒問題(OK)
使用NAOK意味著所有或部分變量都是無關的(例如「不適用」(NA)是正常的(OK))。
當你在任何等式中放入一些來自問題的變量時:如果這個問題(或子問題)被條件隱藏:這將禁用所有等式。
例如:如果Q1的一個子問題被過濾,則count(Q1_SQ1,Q1_SQ2,Q1_SQ3,Q1_SQ4)總是給出一個空字符串。 要計算這個問題中檢查的子問題的數量,可以count(Q1_SQ1.NAOK,Q1_SQ2.NAOK,Q1_SQ3.NAOK,Q1_SQ4.NAOK)。如果子問題被隱藏:表達式管理器返回一個空字符串。
沒有NAOK:如果隱藏了一個問題或一個子問題:表達式管理器總是返回一個空字符串,同樣返回false。
.shown總是使用NAOK系統(如果隱藏了空字符串),但是如果你需要答案的代碼:在問題代碼之後添加.NAOK總是一個好主意。除非你需要它並知道你做了什麼。
另一個示例和信息在覆蓋級聯條件中提供
訪問函數
表達式管理器提供對數學、字符串和用戶定義函數的訪問,如下所示。它具有這些函數的PHP和JavaScript等價物,因此它們在伺服器端(PHP)和客戶端(JavaScript)上的工作方式相同。添加新功能很容易。
已實現的函數
目前提供以下函數:
函數 | 含義 | 語法 |
---|---|---|
abs | 絕對值 | number abs(number) |
acos | 反餘弦 | number acos(number) |
addslashes | Quote string with slashes | string addslashes(string) |
asin | 反正弦 | number asin(number) |
atan | 反正切 | number atan(number) |
atan2 | Arc tangent of two variables | number atan2(number, number) |
ceil | Round fractions up | number ceil(number) |
checkdate | Returns true(1) if it is a valid date in gregorian calendar | bool checkdate(month,day,year) |
convert_value | Convert a numerical value using a inputTable and outputTable of numerical values | number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList) |
cos | 餘弦 | number cos(number) |
count | count the number of answered (non-blank)questions in the list | number count(arg1, arg12, ..., argN) |
countif | Count the number of answered questions in the list equal the first argument | number countif(matches, arg1, arg2, ... argN) |
countifop | Count the number of answered questions in the list which pass the criteria (arg op value) | number countifop(op, value, arg1, arg2, ... argN) |
date | 格式化本地日期/時間 | string date(format [, timestamp=time()]) |
exp | Calculates the exponent of e | number exp(number) |
fixnum | Display numbers with comma as radix separator, if needed | string fixnum(number) |
floor | Round fractions down | number floor(number) |
gmdate | 格式化GMT日期/時間 | string gmdate(format [, timestamp=time()]) |
html_entity_decode | Convert all HTML entities to their applicable characters (always uses ENT_QUOTES and UTF-8) | string html_entity_decode(string) |
htmlentities | Convert all applicable characters to HTML entities (always uses ENT_QUOTES and UTF-8) | string htmlentities(string) |
expr_mgr_htmlspecialchars | Convert special characters to HTML entities (always uses ENT_QUOTES and UTF-8) | string htmlspecialchars(string) |
expr_mgr_htmlspecialchars_decode | Convert special HTML entities back to characters (always uses ENT_QUOTES and UTF-8) | string htmlspecialchars_decode(string) |
idate | Format a local time/date as integer | string idate(string [, timestamp=time()]) |
if | Excel-style if(test,result_if_true,result_if_false) | if(test,result_if_true,result_if_false) |
implode | Join array elements with a string | string implode(glue,arg1,arg2,...,argN) |
intval | Get the integer value of a variable | int intval(number [, base=10]) |
is_empty | Determine whether a variable is considered to be empty | bool is_empty(var) |
is_float | Finds whether the type of a variable is float | bool is_float(var) |
is_int | Find whether the type of a variable is integer | bool is_int(var) |
is_nan | Finds whether a value is not a number | bool is_nan(var) |
is_null | Finds whether a variable is NULL | bool is_null(var) |
is_numeric | Finds whether a variable is a number or a numeric string | bool is_numeric(var) |
is_string | Find whether the type of a variable is string | bool is_string(var) |
join (New in 2.0 build 130129) | Join elements as a new string | join(arg1, arg2, ... argN) |
list | Return comma-separated list of non-blank values | string list(arg1, arg2, ... argN) |
log | The logarithm of number to base, if given, or the natural logarithm. | number log(number,base=e) |
ltrim | Strip whitespace (or other characters) from the beginning of a string | string ltrim(string [, charlist]) |
max | 尋找最大值 | number max(arg1, arg2, ... argN) |
min | 尋找最小值 | number min(arg1, arg2, ... argN) |
mktime | Get UNIX timestamp for a date (each of the 6 arguments are optional) | number mktime([hour [, minute [, second [, month [, day [, year ]]]]]]) |
modulo-function | The modulo function is not supported yet. You can use the floor() function instead | floor(x/y)==(x/y) |
nl2br | Inserts HTML line breaks before all newlines in a string | string nl2br(string) |
number_format | Format a number with grouped thousands | string number_format(number) |
pi | 獲取pi的值 | number pi() |
pow | Exponential expression | number pow(base, exp) |
quoted_printable_decode | Convert a quoted-printable string to an 8 bit string | string quoted_printable_decode(string) |
quoted_printable_encode | Convert a 8 bit string to a quoted-printable string | string quoted_printable_encode(string) |
quotemeta | Quote meta characters | string quotemeta(string) |
rand | Generate a random integer, see this example | int rand() OR int rand(min, max) |
regexMatch | compare a string to a regular expression | bool regexMatch(pattern,input) |
round | Rounds a number to an optional precision | number round(val [, precision]) |
rtrim | Strip whitespace (or other characters) from the end of a string | string rtrim(string [, charlist]) |
sin | 正弦 | number sin(arg) |
sprintf | Return a formatted string | string sprintf(format, arg1, arg2, ... argN) |
sqrt | Square root | number sqrt(arg) |
stddev | Calculate the Sample Standard Deviation for the list of numbers | number stddev(arg1, arg2, ... argN) |
str_pad | Pad a string to a certain length with another string | string str_pad(input, pad_length [, pad_string]) |
str_repeat | 重複字符串 | string str_repeat(input, multiplier) |
str_replace | Replace all occurrences of the search string with the replacement string | string str_replace(search, replace, subject) |
strcasecmp | Binary safe case-insensitive string comparison | int strcasecmp(str1, str2) |
strcmp | Binary safe string comparison | int strcmp(str1, str2) |
strip_tags | Strip HTML and PHP tags from a string | string strip_tags(str, allowable_tags) |
stripos | Find position of first occurrence of a case-insensitive unicode string (starting by 0, return false if not found) | int stripos(haystack, needle [, offset=0]) |
stripslashes | Un-quotes a quoted string | string stripslashes(string) |
stristr | Case-insensitive strstr | string stristr(haystack, needle [, before_needle=false]) |
strlen | Get string length | int strlen(string) |
strpos | Find position of first occurrence of an unicode string (starting by 0, return false if not found) | int strpos(haystack, needle [ offset=0]) |
strrev | Reverse a string | string strrev(string) |
strstr | Find first occurrence of a string | string strstr(haystack, needle[, before_needle=false]) |
strtolower | Make a string lowercase | string strtolower(string) |
strtotime | Parse about any English textual datetime description into a Unix timestamp | int strtotime(string) |
strtoupper | Make a string uppercase | string strtoupper(string) |
substr | Return part of an unicode string | string substr(string, start [, length]) |
sum | Calculate the sum of values in an array | number sum(arg1, arg2, ... argN) |
sumifop | Sum the values of answered questions in the list which pass the criteria (arg op value) | number sumifop(op, value, arg1, arg2, ... argN) |
tan | 正切 | number tan(arg) |
time | Return current UNIX timestamp | number time() |
trim | Strip whitespace (or other characters) from the beginning and end of a string | string trim(string [, charlist]) |
ucwords | Uppercase the first character of each word in a string | string ucwords(string) |
unique | Returns true if all non-empty responses are unique | boolean unique(arg1, ..., argN) |
計劃或被考慮的函數
計劃(或正在考慮)但尚未實施的其他函數包括以下內容。其中一些是為了與另一個調查工具向後兼容。
語法 | 含義 | 注釋 |
---|---|---|
e() | 返回e的值 | |
formatDate(X,PAT) | 返回根據Java數據格式模式格式化的日期X的字符串值 | |
formatNumber(X,PAT) | 返回根據Java編號格式化的數字X的字符串值格式模式PAT | |
getAnsOption(X) | 返回與所選選項對應的文本對應答案X | 這與X.shown相同 |
返回與節點X的索引Y處的選項對應的文本 | ||
getRelevance(X) | 返回問題X的相關方程式 | |
getStartTime() | 返回與訪問開始時的系統時間對應的日期 | |
getType(X) | 返回數據類型的字符串名稱 - 例如*NA* if isNA() | |
gotoFirst() | 跳轉到第一組相關問題 - 這違反了系統的正常流程 | |
gotoNext() | 跳轉到下一組相關問題 - 這違反了系統的正常流程 | |
gotoPrevious() | 跳轉到上一組相關問題 - 這違反了系統的正常流程 | |
isAsked(X) | 如果答案既不是*NA*、*INVALID*,也不是*UNASKED* ,則返回true | |
isInvalid(X) | 如果答案類型為*INVALID*,則返回true | |
isNA(X) | 如果答案類型為*NA* ,則返回true | |
isNotUnderstood(X) | 如果答案類型為*HUH* ,則返回true | |
isRefused(X) | 如果答案類型為*REFUSED* ,則返回true | |
isSpecial(X) | 如果答案類型為 *UNASKED*、 *NA*、 *REFUSED*,、*INVALID*、 *UNKNOWN*或*HUH*,則返回true | |
isUnknown(X) | 如果答案類型為*UNKNOWN* ,則返回true | |
jumpTo(X) | 跳轉到包含指定問題的組 - 這違反了系統的正常流程 | |
jumpToFirstUnasked() | 跳轉到第一個未解決的問題 |
|
lastIndexOf(X,Y) | 返回字符串X中字符串Y的最後一個索引(基數為0)。如果Y中不包含Y,則返回-1 | |
list(X,...) | 一個包含逗號分隔的正值列表的字符串,其中"和"分隔最後兩個 | |
mean(X,...) | 返回值列表的平均值 | |
numAnsOptions(X) | 返回問題X的答案選項的數量 | |
orlist(X,...) | 包含的字符串逗號分隔的正值列表,用"或"分隔最後兩個 | |
parseDate(X,PAT) | 返回用Java日期格式模式PAT解析的字符串X的日期值 | |
parseNumber(X,PAT) | 返回用Java數字格式模式PAT | |
showAllResponsesExcept( questionList,attributeList,attributeTitleList) | questionList =以管道分隔的問題標識符列表; attributeList =管道分隔的屬性列表(如問題#,標題,文本,類型 - 因此您可以決定要顯示的內容); attributeTitleList =管道分隔的表頭列表,因此可以使報告國際化。 | |
showTheseResponses( questionList,attributeList,attributeTitleList) | questionList =管道分隔的問題標識符列表; attributeList =管道分隔的屬性列表(如問題#,標題,文本,類型 - 因此您可以決定要顯示的內容); attributeTitleList =管道分隔的表頭列表,因此可以使報告國際化。 |
表達式管理器知道哪些變量是本地的
為了正確構建頁面JavaScript,表達式管理器需要知道頁面上設置了哪些變量,以及它們的JavaScript ID是什麼(例如,對於document.getElementById(x))。它還必須知道在其他頁面上設置了哪些變量(以便它可以確保所需的變量<input type='hidden' value='x'> 欄位存在並填充)。
級聯條件
如果任何變量不相關,則整個等式將是無關緊要的(假)。例如,在下表中,N / A表示其中一個變量不相關
操作符 | 示例 | a | b | 結果 |
---|---|---|---|---|
+ (unary) | +a | N/A | false | |
! | !a | N/A | false | |
== (or eq) | a == b | N/A | 5 | false |
== (or eq) | a == b | N/A | 0 | false |
== (or eq) | a == b | N/A | N/A | false |
!= (or ne) | a != b | N/A | 5 | false |
!= (or ne) | a != b | N/A | N/A | false |
!= (or ne) | a != b | N/A | 0 | false |
> (or gt) | a > b | N/A | 5 | false |
>= (or ge) | a >= b | N/A | 5 | false |
< (or lt) | a < b | N/A | 5 | false |
<= (or le) | a <= b | N/A | 5 | false |
and | a and b | N/A | 5 | false |
and | a and b | N/A | N/A | false |
or | a or b | N/A | N/A | false |
or | a or b | N/A | 5 | false |
+ | a + b | N/A | 5 | false |
* | a * b | N/A | 5 | false |
/ | a / b | 5 | N/A | false |
() | (a) | N/A | false | |
(exp) | (a && b) | N/A | 5 | false |
(exp) op (exp) | (b + b) > (a && b) | N/A | 5 | false |
function | sum(a,b,b) | N/A | 5 | false |
function | max(a,b) | N/A | 5 | false |
function | min(a,b) | N/A | 5 | false |
function | implode(', ',a,b,a,b) | N/A | 5 | false |
function | if(a,a,b) | N/A | 5 | false |
function | is_empty(a) | N/A | false | |
function | is_empty(a) | 0 (or blank) | true | |
function | !is_empty(a) | N/A | false |
重寫級聯條件
假設你要顯示所有相關答案的總計。您可以嘗試使用等式 {sum(q1,q2,q3,...,qN)}。然而,這被內部轉譯為LEMif(LEManyNA('q1','q2','q3',...,'qN'),,sum(LEMval('q1'),LEMval('q2'),LEMval('q3'),...,LEMval('qN')))。因此,如果任何值q1-qN不相關,則等式將始終返回false。在這種情況下,sum()將顯示0,直到所有問題都得到回答。
為了解決這個問題,每個變量都可以添加一個「.NAOK」後綴(意思是「不適用」)。在這種情況下,會發生以下行為。假設你有一個變量q1.NAOK
- q1沒有添加到LEManyNA()子句中
- LEMval('q1')將繼續檢查響應是否相關,並將返回 “” 如果不是(因此個別不相關的反應將被忽略,但它們不會使整個表達無效)。
因此,運行總問題的解決方案是使用方程式sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK)。
使用.NAOK後綴還可以讓作者設計具有多種可能路徑的調查,然後在以後匯聚到公共路徑上。例如,受試者以一種超出正常反應範圍的方式回答調查。作者可以提醒受試者他們可能無法獲得有效結果,並詢問他們是否真的想繼續進行調查。如果他們說「是」,則會顯示其餘問題。 「其餘問題」的條件將檢查初始回答是否在正常範圍內得到回答,或者受試者是否對只有在正常範圍之外回答的相關問題說「是」。
表達式管理器如何支持條件微裁剪?
以下是微裁剪的示例(其中問題類型=='expr'表示公式):
問題代碼 | 相關性 | 問題類型 | 問題 |
---|---|---|---|
name | 1 | text | 你叫什麼名字? |
age | 1 | text | 你多大了? |
badage | !is_empty(age) | expr | {(age<16) or (age>80)} |
agestop | badage | message | 對不起,{name}, 對這個測試而言,你太{if( (age<16),'年輕',if( (age>80),'老','middle-aged') ) } 了。 |
kids | !badage | yesno | 你有孩子嗎? |
parents | 1 | expr | {!badage && kids=='Y'} |
numKids | parents | text | 你有幾個孩子? |
kid1 | parents && numKids >= 1 | text | 你的第一個孩子多大了? |
kid2 | parents && numKids >= 2 | text | 你的第二個孩子多大了? |
kid3 | parents && numKids >= 3 | text | 你的第三個孩子多大了? |
kid4 | parents && numKids >= 4 | text | 你的第四個孩子多大了? |
kid5 | parents && numKids >= 5 | text | 你的第五個孩子多大了? |
sumage | 1 | expr | {sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)} |
report | parents | yesno | {name},你現在{age} 歲,並且有{numKids}個孩子. The sum of ages of your first {min(numKids,5)} kids is {sumage} |
所有這些問題都可以在一個頁面上(例如在同一組中),並且只顯示相關問題。此外,當你輸入子項的年齡時,最後一個問題中的sum()表達式將在頁面上動態更新。
表達式管理器通過使用named包圍每個表達式來提供此功能<span> 元素。每次值更改時,它都會重新計算應該出現的表達式 <span> 元素並重新生成顯示。你可以在同一頁面上擁有數十個甚至數百個這樣的定製表達式,並且頁面將在單個屏幕刷新中重新顯示所有這些表達式。
將LimeSurvey 1.91+映射到表達式管理器功能
Old Feature | New Feature | Comments |
---|---|---|
條件 | 條件 | 你可以使用非常複雜的條件方程式,並訪問更廣泛的變量 |
評估 | 方程式 | 任何評估分數都可以重新組織成方程式。這既可以確保將分數寫入資料庫,也可以讓你看到當前頁面上分數值的動態變化 |
替換 | 表達式管理器 | 核心引擎獲取輸入字符串並將花括號中的所有內容視為表達式 - 因此它處理所有歷史替換類型。為了避免搞亂嵌入式JavaScript,表達式管理器只處理花括號之間的內容,只要(a)花括號內沒有前導空格或尾隨空格 - 例如{expr}是表達式,但{expr},{expr},和{expr}不是表達式。此外,Expression Manager不會在其自己的字符串中處理內容(例如{list('hi','there {braces}')}生成「hi there {braces}」)。它也忽略了轉義的花括號(例如\ {這不是表達式\}) |
驗證 | 表達式管理器 | 計劃是採用當前的最小/最大問題屬性並擁有表達式管理器處理它們。這樣,最小/最大值可以是表達式本身 |
語法突出顯示
為了幫助輸入和驗證表達式,EM提供了語法突出顯示功能,具有以下功能:
語法突出顯示的類型和含義
顏色 | 實例 | 含義 | 工具提示 | 注釋 |
---|---|---|---|---|
棕褐色背景 | Sample | 整個方程式 | none | 花括號中被識別為方程式的任何東西(例如,沒有前導或尾隨空白)將用棕褐色背景進行顏色編碼,以幫助將其與周圍文本區分開來 |
粗體紅色文本 | Sample | 錯誤 | 關於錯誤的一些解釋 | 可以是一個未知變量或函數中的錯誤,……調查可以被完全破壞,所以不要向公眾用戶展示。 |
藍色文本 | Sample | 函數名稱 | 含義和允許語法 | 函數名稱,或者應該是函數的東西,因為它們後跟一個左括號,以粗體藍色文本顯示。工具提示顯示函數的含義和允許的語法。 |
灰色文本 | Sample | 字符串 | none | 單引號和雙引號字符串以灰色文本顯示 |
青色文本 | Sample | variable set on the same page, | [name or SGQA code]: question; value; answerList showing codes for each value | Any variable that is set on the same page to the current question is shown in cyan text, showning it can be updated in javascript. The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set). If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show. |
green text | Sample | variable set on a prior page | [name or SGQA code]: question; value; answerList showing codes for each value | Any variable that is set on a prior page is shown in bold green text. The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set). If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show. |
bold pink text | Sample | variable set on a later page in general : empty at survey start, but can be filled with index or move previous | [name or SGQA code]: question; value; answerList showing codes for each value | Any variable that is set on a prior page is shown in bold pink text. The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set). If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show. |
bold tan text | Sample | a lime replacement value | the value | Lime Replacement Strings (like {TOKEN:xxx}, {PRIVACY_MESSAGE}) are shown in bold tan text. |
red text | Sample | assignment operator (=) | warning message | If you use one of the assignment operator (=) that operator will be displayed in red text. This is meant to help prevent accidental re-assignment of values when you really meant to check whether a == b instead of setting the value of a = b. |
normal black text | Sample | punctuation | none | All other punctuation within the expression is shown as normal black text. |
red-boxed text | a bold red line surrounds the error | syntax error | description of the error | Any detected syntax errors are shown by surrounding the error with a red box. The tooltip shows the error. Examples include unmatched parentheses, use of undefined functions, passing the wrong number of arguments to functions, poorly structured expressions (e.g. missing operators between variables), trying to assign a new value to a read-only variable, trying to assign values to non-variables, or using unsupported syntax. Note that the syntax error dectection system may only report one error in an expression even if there are multiple errors; however, if any errors are detected, at least one error will be shown. |