When working with a nested model, you may want to access and printout the details of elements within a hierarchy recursively. Since the level of model can be unlimited, it is hard to write a custom element template with a chunk of code repeated a certain number of time, not to mention this way of coding will make the template messy and hard to maintain. To solve this problem you can form a recursive template call by applying the concept of template referencing. If you are a programmer, the idea is exactly the same as a recursive method call in programming. All you need to do is to add the element in the appropriate place in the template, to instruct the template engine to process the same template, forming a self-loop. We will walk you through the details in this article.
<?xml version="1.0" encoding="UTF-8"?> <ElementBaseInitiationBlock> <!-- Name of package --> <Property style="@heading+" property="name"/> <ParagraphBreak/> <!-- Name of classes in this package --> <IterationBlock modelType="Class"> <Property property="name"/> <ParagraphBreak/> </IterationBlock> <!-- Call the same template to process the child packages --> <IterationBlock modelType="Package"> <Reference template="Sub-Classes (Recursive)"/> </IterationBlock> </ElementBaseInitiationBlock>
How to use the sample code?
We have prepared a sample project to show you how the sample code works. Please follow the steps below to create a template with the sample code. An explanation of code will be given in the next section.
- Download JDK-1.8_javax_only.zip. Extract it to obtain JDK-1.8_javax_only.vpp project file. Open it in Visual Paradigm.
- Open Doc. Composer by selecting Tools > Doc. Composer from the application toolbar.
- Select Build Doc from Scratch.
- Open Model Explorer and select any package.
- Right click on any template listed in the Template pane and select Duplicate… from the popup menu.
- In the Edit Template window, enter Sub-Classes (Recursive) as the name of template.
- Replace the template code with the sample code provided in the previous section.
- Click OK.
- Now, select any package in Model Explorer, and then drag the template Sub-Classes (Recursive) from the Template pane onto the document. Depending on your package selection, you should obtain a document that looks like the one below.
Explanation of sample code
The sample project contains a lot of packages and classes, forming a nested hierarchy. What the sample code does is to drill down the packages recursively and to output the name of all child packages and classes.
The template can be divided into three parts. The first part output out the name of package. The second part walks through the classes in the package and to output their names. The third part walk through the sub-packages inside the current package. And, apply the same template for each sub-package.
Take a look at the first part first:
<!-- Name of package --> <Property style="@heading+" property="name"/> <ParagraphBreak/>
Pay attention to the use of dynamic heading style @heading+. In a document that involves outputting content from a nested model hierarchy, it’s pretty common to have headers in multiple levels, presented as different header styles like Heading 1, Heading 2, etc. The use of dynamic heading number is to serve this purpose. Instead of giving a fixed style like Heading 1, Heading 2, we let the template engine to decide the numbering level to use, based on the flow of template processing. If you want to know more about the use of dynamic heading style, click here to read Chapter 7. Doc. Composer – Writing Element Templates of Visual Paradigm User’s Guide.
Now, take a look at the third part of the template:
<!-- Call the same template to process the child packages --> <IterationBlock modelType="Package"> <Reference template="Sub-Classes (Recursive)"/> </IterationBlock>
This is the most important part of the template. Without it, only the immediate level of child classes will be processed.
The use of instructs the template engine to carry on by applying the template specified by the attribute template. In this case, since the that wraps the element enforces that only package will be processed, the reference will be applying the Sub-Classes (Recursive) template defined for package. Doing so forms a recursion. Things end when no more sub-packages are found.
Note that the template defined is based on specific type of project data, in this case, a package. If you want to process another type of model elements, say, a sub-system, then you need to define the template again for sub-system. In other words, if your model hierarchy has not only package, but also other kinds of parent container and you want them all be included in the recursion, you need to define the same templates for all of them.