Im processing the XML file, which is simplified, looks something like this:
<resources> <resource id="a"> <dependency idref="b"/> </resource> <resource id="b"> </resource> </resources>
The XSLT stylesheet should handle the resource you are interested in, which I will call the root resource, and all recursive dependencies. Dependencies are other resources uniquely identified by their id attribute.
It does not matter if the resource is processed twice, although it is preferable to process each required resource only once. It also does not matter in which order the resources are processed.
It is important that the root resource and its recursive dependencies are handled only . We cannot just process and do all the resources.
The naive implementation is this:
<xsl:key name="resource-id" match="resource" use="@id"/> <xsl:template match="resource"> <xsl:apply-templates select="key('resource-id', dependency/@idref)"/> </xsl:template>
This implementation is great for the example above, as well as in many cases in the real world. It has the disadvantage that it often processes the same resource more than once, but, as indicated above, this is not very important.
The problem is that sometimes resources have cyclic dependencies:
<resources> <resource id="a"> <dependency idref="b"/> <dependency idref="d"/> </resource> <resource id="b"> <dependency idref="c"/> </resource> <resource id="c"> <dependency idref="a"/> </resource> <resource id="d"/> </resources>
If you use a naive implementation to process this example and start by processing a , b or c , you get infinite recursion.
Unfortunately, I can not control the input data, and in any case, cyclic dependencies are quite permissible and allowed by the corresponding specification.
Ive come up with various partial solutions, but nothing works in all cases.
An ideal solution would be a general approach to prevent node processing more than once, but I don't think this is possible. In fact, I suspect that this problem cannot be solved.
If this helps, I have most of EXSLT (including functions). If necessary, I can also pre-process the input with any number of other XSLT scripts, although it is preferable not to do excessive preprocessing of resources that usually do not end with the output.
What I can do is switch to processing this using another language (at least without a significant reorganization). I also cannot use XSLT 2.0.
Any ideas?