Sometimes, you will want to use a more complex substitution apart from just taking an attribute from the XML. For instance, you might want to display not the name of a person, but the length of their name. XPath provides syntax to retrieve this using the built-in
string-length method. However, you cannot use a expression that returns a number in the query, as the query must return DOM nodes as results. In this case, we use an expression that returns the nodes as in earlier examples, and use some additional syntax of the query to get the length of the names.
<vbox datasources="people.xml" ref="*" querytype="xml"> <template> <query expr="person"> <assign var="?namelength" expr="string-length(@name)"/> <assign var="?siblings" expr="count(../*) - 1"/> </query> <action> <hbox uri="?" align="center"> <button label="?name"/> <label value="?gender"/> <label value="?namelength"/> <label value="?siblings"/> </hbox> </action> </template> </vbox>
assign elements are placed as children of the
query element. It allows us to declare additional variables that may be used in the action body. The
expr attribute specifies the XPath expression and the
var attribute specifies the variable to assign to. Note that while the query expression uses the root node (or reference node) as the XPath context, the expressions for the
assign element are evaluated using each result node as the context.
For each result, the
?namelength variable will be assigned the length of the name attribute on the result node, and the
?siblings variable will be assigned the number of sibling nodes the result has. (In this case, the number of XML node siblings in the document, not the number of real siblings the people have, clearly the people in the datasource aren't actually siblings). Naturally, the number of siblings will be the same for all children, but you could imagine a more complex query expression that generated nodes where this wasn't actually the case.
The two variable assignments may then be used in the action body to replace attributes in the generated content. If a variable is used in the action that doesn't correspond to one declared in an
assign element, the default behaviour is to take the corresponding attribute on the result node. Here, the two attributes 'name' and 'gender' will be taken from the XML data, as in previous examples.