Debugging problems with a template can be difficult as many problems are logic errors that are often not possible to determine automatically. For example, if you spell a value wrong, no data may be returned, but the template system won't know that that this was because of a spelling error, or simply that there shouldn't be any data anyway. Fortunately, some debugging and logging support is provided with templates that may help.
Logging Template Results
There are two main ways in which template errors may be detected. The first debugging method involves logging all new results that apply to the template due to the data changing as well as logging results that are changed or removed. In addition, each result generated when the template is first created and initialized is logged. This logging of result changes is not done by default; it must be enabled with a flag.
<vbox datasources="..." flags="logging"/>
The flags attribute on the root element of the template should include the
logging flag. If other flags are used as well, separate them with spaces. Enabling logging will output details to the error console for each result. The error console can be found on the Firefox Tools menu. This logging of results can be very useful for debugging, but remember to remove this flag when you have finished and the template works correctly, as the logging can take up extra time that is not necessary when the template is working.
Each result is logged in a form much like the following:
In template with id root using ref http://www.some-fictitious-zoo.com/birds New active result for query 2 matching rule 1: http://www.some-fictitious-zoo.com/birds/emperorpenguin
In the example above, a new result has been added. For references, the value of the template's id and ref attributes are provided in each logged message. This is useful if multiple templates are being used.
The second line gives details about the new result. The id of the result is specified at the end, in this case 'http://www.some-fictitious-zoo.com/b...emperorpenguin'. This corresponds to the id attribute set on a generated row. For an RDF datasource, this will be the result's resource. For other datasources, this may be a somewhat random value. However, calling getElementById using this id will retrieve the generated content for that result if you want to further study the content that was generated.
The example also specifies 'query 2 matching rule 1'. This indicates that the result is for the second <query> element. If only one <query> is used, naturally this will always indicate a query of 1. In addition, this result matches the first <rule> of query 2. This information may be used to determine if results are not matching the correct rules. If you, for example, were expecting rule 2 to match, examine the rules and ensure that the logic is correct.
The final piece of information is the phrase 'New active result'. This indicates first, that this is a new result, as opposed to a result being removed, and second, that this result is 'active'. Being active means that the result is not being overridden by an earlier query. As this example implies multiple queries are being used, we can determine that the first query did not provide a result with the given id, and that the result from the second query is used instead. This allows us to narrow down what query and rule is being used to generate the content. If the query was inactive, the log would say 'New inactive query'.
In template with id root using ref http://www.some-fictitious-zoo.com/birds Removed inactive result for query 2 (active query is 1): http://www.some-fictitious-zoo.com/birds/barnowl
In this example, a result with the id 'http://www.some-fictitious-zoo.com/birds/barnowl' has been removed. Again, it was a result from query 2. However, note that the result is specified as being 'inactive'. This is because the result is also supplied by the first query which overrides it. The template's generated content will not change in this example as an active result is not changing. In other words, the generated content will only change when active results are involved.
In template with id root using ref http://www.some-fictitious-zoo.com/birds Removed active result for query 1 (no new active query): http://www.some-fictitious-zoo.com/birds/barnowl
This is a similar example, except that a result with the same id is being removed from the first query instead. Note that this result is active and an indication is made in parantheses that there is no longer any active query. This indicates that the generated content will be removed. The log may instead indicate that another query is active; this would mean that the content for a different query is now generated.
To summarize, the following forms of message may be logged:
- New active result for query 1 matching rule 2
- A new data result has been added. In this example, the result matches the second rule of query 1. The generated content is from rule 2 of query 1.
- New inactive result for query 2 (overridden by query 1)
- A new data result has been added for query 2, but an earlier query 1 overrides it. The generated content is still from the first query, so the content has not changed.
- New inactive result for query 1 (didn't match a rule)
- A new data result has been added but none of the rules matched so no content was generated.
- Removed active result for query 1 (new active query is 2)
- A result no longer matches and the content for it was removed. However, the second query for that id still matches, so new content will be generated for that second query instead.
- Removed active result for query 1 (no new active query)
- A result no longer matches, and content is removed. No other content will replace it.
- Removed inactive result for query 2 (active query is 1)
- A result no longer matches, but it is inactive and doesn't have any content. This is because the first query overrides it.
- Removed inactive result for query 2 (no new active query)
- A result no longer matches, but it is inactive and doesn't have any content. However, no other query overrides it. No changes to the content will occur.
The second type of template error is a syntax error is the template rules, for example, a missing attribute or a tag out of place. These types of errors are also logged to the console, however, these types of errors are logged whether the
logging flag is set or not. The following lists the errors that can occur and an explanation of what the problem is.
- querytype attribute doesn't specify a valid query processor
- This error indicates that the
querytypeattribute is set to an unrecognized value. Only the 'rdf', 'xml' and 'storage' values are provided by default. If you are using a custom query processor, it may indicate that it is not installed or set up properly.
- unexpected <queryset> element
- A <queryset> element was placed in an invalid location; they should be placed directly inside the <template> element with no other kinds of elements as siblings.
- no member variable found. Action body should have an element with uri attribute
- The member variable could not be determined. You should specify an element inside the first <action> body with a uri attribute. You can also specify the
memberattribute on the template. Either way, the member variable isn't known so it isn't clear what value to use for each generated result id.
- <where> element is missing a subject attribute
- Every <where> should have a
subjectattribute that specifies what you are comparing.
- <where> element is missing a rel attribute
- Every <where> should have a
relattribute that specifies what relation condition you are checking.
- <where> element is missing a value attribute
- Every <where> should have a
valueattribute that specifies what you are comparing to.
- <where> element must have at least one variable as a subject or value
- This indicates that you have used a <where> element that doesn't use any variables either in the
subjectattribute or the
valueattribute. Naturally, this rule will always match so it has no use. This error is often caused by typing errors.
- <binding> requires a variable for its subject attribute
subjectattribute on a <binding> element has to be variable (a value beginning with a question mark).
- <binding> element is missing a predicate attribute
predicateattribute on a <binding> element has not been set.
- <binding> requires a variable for its object attribute
objectattribute on a <binding> element has to be variable (a value beginning with a question mark).
- expected <content> to be first
- For an RDF template, when using the full query syntax, the <content> element must always appear before any other elements. In other words, this error occurs because either the <content> element was missing or was placed after a <member> or <triple> element.
- <member> requires a variable for its container attribute
containerattribute on a <member> element has to be variable (a value beginning with a question mark). This error can also occur if the
containerattribute was not set.
- <member> requires a variable for its child attribute
childattribute on a <member> element has to be variable (a value beginning with a question mark). This error can also occur if the
childattribute was not set.
- <triple> should have at least one variable as a subject or object
- Both the
objectattributes of a <triple> element have been set to a non-variable. This will have no effect so an error is output indicating this.
- <triple> requires a variable for its subject attribute
subjectattribute on a <triple> element has to be variable (a value beginning with a question mark). This error can also occur if the
subjectattribute was not set.
- <triple> should have a non-variable value as a predicate
predicateattribute on a <triple> element has either not been set or has been set to a variable. Instead, it has to be set to a resource predicate.
- <triple> requires a variable for its object attribute
objectattribute on a <triple> element has to be variable (a value beginning with a question mark). This error can also occur if the
objectattribute was not set.
- neither container or child variables of <member> has a value
- This indicates that a <member> was being checked and yet neither the variables specified for the container or the child have a value for a result. This error will occur while processing a result and will often repeat for each result. This error generally indicates an error in the logic of the template. Common errors are misspelled variable names or <member> and <triple> elements placed in the wrong order. Note that this error does not occur simply because, for example, a particular container has no children; it means that a logic error in the query implies that a variable could never be computed properly. An example is given below this list of errors.
- neither subject or object variables of <triple> has a value
- Similar to the previous error but for the <triple> element. Either the subject or object variables could never be set to a value for a result.
- XPath expression in query could not be parsed
- For XML datasources, a
queryattribute has an XPath expression that is not valid.
- XPath expression in <assign> could not be parsed </assign>
- For XML datasources, an <assign> element has an XPath expression that is not valid.
- XPath expression in <binding> could not be parsed
- For XML datasources, a <binding> element has an XPath expression that is not valid.
The two errors where neither variable of either a <member> or <triple> have a value deserve some examples.
<content uri="?uri"> <member container="?uri" child="?person"> <triple subject="?person" predicate="http://example.com/name" object="?name"/> <content uri="?uri"> <member container="?uri" child="?human"> <triple subject="?person" predicate="http://example.com/name" object="?name"/>
Note that subtle difference in these examples. The
child attribute on the <member> element is different. The first example generates no error and is a common template query pattern. The second example, however, has an error. The triple refers to two variables (?person and ?name) that aren't used in earlier tags. It's likely that the author here had meant to use the first example, or had meant to change the value of the
subject attribute to
?human to match.
However, it is important to note that an error will not be printed simply if data didn't exist for a particular result. In the above example, some people may not have names. These people will not match the query but it will not cause an error. Thus, if no error is logged, it generally indicates an issue with the data or that the data does not match the query being used. We could debug this by removing parts of the query bottom up, for instance, removing the <triple> element completely and seeing whether any results or content is generated. Remember to use the
logging flag as described above to see whether any results are being generated.
Unfortunately, detecting network or parsing errors with the data itself can be difficult. Naturally, semantic errors in the data in the datasource can't be easily detected automatically. However, for XML datasources, you can at least check the builder's datasource to see whether the XML data was loaded and parsed correctly. If null, then the datasource could not be loaded, or hasn't yet been loaded. If the datasource load and parsing was successful, the datasource will be set to the XML document. For example:
if (root.builder.datasource instanceof XMLDocument) alert("XML Datasource loaded OK");
Be careful, as the datasource will only be set once the document has finished loading and has been parsed, so don't check this property too early. You may also get an error if you manipulate or analyze the template while the datasource is loading. You could iterate and wait using a timer. Future versions may include other features to make it easier to debug problems with data loading.