xAPI data types¶
The parts of a statement, as plain serializable types. An xAPI statement is "actor verb object", with optional result and context — these are those pieces.
| File | What it is |
|---|---|
XApiStatement | The whole thing: actor, verb, object, result, context, id, timestamp |
XApiActor | Who did it — an agent, identified by mbox, account, or openid |
XApiVerb | What they did — an IRI plus a display name |
XApiActivity | What they did it to — an IRI plus name and description |
XApiResult | How it went — score, success, completion, response, duration |
XApiContext | Registration, and the activity hierarchy the statement sits in |
Everything optional is nullable, and that is load-bearing¶
XApiResult.success and completion are bool?; every field on XApiScore is float?. Omitting one says nothing, rather than saying no.
This matters more in xAPI than in SCORM. A statement about answering a question carries a response and a success and usually no score at all, and a statement that reported score: 0, completion: false because those are the defaults for their types says something false about the learner.
XApiScore.Raw, and the rejection it avoids¶
Use XApiScore.Raw(raw, min, max) rather than setting the fields by hand. It derives scaled from the range and clamps it to -1..1, which the specification requires.
It also clamps raw into min..max, which the specification equally requires and which is the less obvious half: an LRS is obliged to reject the entire statement when raw sits outside the stated range. So Passed(105) against the default 0–100 range used to lose the pass completely — the statement was refused, and the queue then correctly discarded it as permanently rejected.
A clamped score is a reporting inaccuracy. A rejected statement is a lost pass. The clamp is the better trade, and it logs a warning naming the real value so the range can be fixed.