Is it possible to match 'Any node not already matched/handled'? Preferably without making my style sheet into an enormous for-each/Choose statement, as the current ordering is critical.
The project is still in development and already being used in the live environment, so the code is, simply put, in a state of rapid flux in response to live data we're getting in. I am generating a PDF document via FO from XML that may have nodes in it that I don't know about yet, and would like to add a "fail over" instruction to my XSL-FO transform that puts all the unaccounted-for nodes at the beginning of the document in bright red, to speed up discovery.
I can't just ignore surprise nodes, as the data needs to be handled. The quicker I can find "orphan" data, the quicker I can get it properly handled and out the door.
I have tried playing around with <xsl:template match="*">...</xsl:template>
and various priority="" settings, but of course it applies to every node.
For example, I might have this in one section because these XML blocks are not guarenteed to come in the correct output order. (Code block formatting is not working for me - four space indent results in nothing, sorry :(
<xsl:template match="AccountSummary">
<fo:block margin-left="2" space-before="1" space-after="1" text-align="center">
<xsl:apply-templates select="Label"/>
</fo:block>
<xsl:apply-templates select="AccountInfo"/>
<xsl:apply-templates select="AccountProfile"/>
<xsl:apply-templates select="ChangeInValueOfAccounts"/>
<!-- ... more goes here -->
</xsl:template>
I would like to do something like
<xsl:template match="AccountSummary">
<fo:block margin-left="2" space-before="1" space-after="1" text-align="center">
<xsl:apply-templates select="Label"/>
</fo:block>
<xsl:apply-templates select="AccountInfo"/>
<xsl:apply-templates select="AccountProfile"/>
<xsl:apply-templates select="ChangeInValueOfAccounts"/>
<!-- ... more goes here -->
<xsl:for-each select="not otherwise matched">
<!-- call zomgRED template -->
</xsl:for-each>
</xsl:template>
Ideally I'd rather the zomgRED
s to be at the top, but at the bottom will work too. Or flagged with text markers. Anything to spit out the text in the final document instead of silently eating it.
Here's how you might be able to get some flavor of what you are looking for. Though no pushing the unprocessed nodes up to the top:
1) have the identity transformation in your stylesheet:
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
2) make sure you call <xsl:apply-templates select="*"/>
from all other more specific templates to let the parser going
The idea is that your specific templates handle the intended transformation to XSL-FO while the identity transform just dumps out everything else into the result tree. The recursive calls will ensure you actually touch all nodes (this is the only way to get them "on record") and the identity transformation will match those you didn't catch otherwise.
That #2 advise can actually get in a way of your XSL-FO logic so may not really be feasible, I can't tell without having an example input and your current XSL-FO transform. Maybe add it to the question?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With