A query that exists inside another query is considered to be nested. Query nesting in RPE has two aspects:
Both aspects of nesting queries are important and depending on usage produce very different results. This article intends to briefly explain how nesting works and what are its the most common pitfalls.
Summary: when designing templates you should make sure that:
- the physical nesting of your queries matches the logical structure of your document
- the logical nesting of your queries ( the contexts of your queries) is correct
- your test data is simple but not too simple – some of the errors caused by incorrect nesting are quite simple and testing on small data will produce results that are apparently correct.
Definition: a query B is context nested in query A when its context property is set to be the identifier of query A. This makes query A the parent of query B and query B a child of query A.
Note: The template elements on which the queries are defined must also be physically nested but this is enforced by Document Studio.
Context nesting can only occur for queries from the same data source and whose schema expressions are compatible.
Example: /Project/Requirements and /Project/Requirements/PRRequirement are queries that can be nested as the second query contains the first one.
Evaluating context nested queries
A nested query is always resolved ( data matching occurs) inside the result of its context parent. In other words the match for the parent query defines the context for its nested child queries.
Using the above example, RPE evaluates queries in the following way:
- While the XML is not finished
- find a match for $3
- find all matches for $4 inside the current XML element ( the match for $3). When that elements end than $4 is considered to be complete and the execution will go back to 1.a and will search for the next $3 match
- find a match for $3
Result: a document where for each $3 occurrence it’s children $4 entries are rendered.
Choosing the context
When a query is inserted in RPE the list of all possible parents is calculated by RPE. Most often there is 0 or 1 query that can be used as parent but there are also cases when more options are available. In such cases make sure you pick the right context.
In the scenario depicted in the screenshot from figure 1 the logical choice is $4. And as a rule of a thumb the “longer” query is usually the correct candidate.
Incorrect nesting – wrong parent context
This is a common mistake when designing templates with RPE.
So what happens if the wrong context is chosen. In the above example if $3 would have been chosen instead of $4 the result would have been that for each /Project/Requirements in the XML document all the /Project/Requirements/PRRequirement/Revisions would be iterated.
Result: a document where for each $3 occurrence all the $4 from the entire document are rendered.
If the XML has only 1 /Project/Requirements entry than there is no difference and the results might look good but as soon as you have 2 entries you will get data duplication in the results or RPE might complain about queries not being nested in the most natural order ( warning 3577).
Definition: a query B is considered nested in query A when it’s physically located under query A but its context property is not the id of query A ( it’s either empty or it’s a different query).
Placement nesting does not require a parent-child relationship between the queries involved. This means that this nesting is possible even for queries that come from different data sources. And actually that is the main usage scenario for this type of nesting.
If the queries are from the same data source RPE will first try to see if they can be used in “context nesting. If that is possible the context dialog will be shown and you need to choose “none” when RPE asks for the context query.
Evaluating placement nested queries
RPE deals with such queries in the following way.
- Find first match of the parent query
- Find all matches for the nested query.
An important note to make here is that even if the queries come from the same data source RPE will handle them as if they were different. This means RPE will read the XML data twice, even if identical.
Incorrect nesting- wrong parent
Placement nesting is usually employed when reading data from linked data using Dynamic Data Sources. Using placement nesting with queries from the same data source it’s uncommon and it’s usually a sign of template error. This results in undefined behavior which can ranged from duplicated data to warning 3577.
In the above picture, query 9 is defined in the context of query $4 yet it is physically placed inside query $7 ( the black border shows the nesting). The above template says “for each requirement give me its full tag, all its revisions and for each revision give me the label of the revision and the requirement’s text” when the author most likely meant “for each requirement give me its full tag, all its revisions and for each revision give me the label of the revision. After that give me the requirement’s text”.
A correctly nested template looks like the one below ( notice that $7 no longer includes query $10):