SGML Inclusions and infinitive recursion (in XSLT)
Just when you thought you'd never answer another question about SGML inclusions. . . I'm working with the XML files produced by Norm Walsh's tool DTDParse. These files represent an SGML or XML DTD. In my case, it's SGML DTDs. I've written a transformation that produces an HTML view of the DTD. It's quite handy, but there's one thing I can't quite get to work and I really need to resolve this issue: inclusions. Here's a snippet of the kind of output in the XML file I'm working with: <dtd> <element name="HEAD" stagm="O" etagm="O" content-type="element"> <content-model-expanded> <and-group> <element-name name="TITLE"/> <element-name name="ISINDEX" occurrence="?"/> <element-name name="BASE" occurrence="?"/> </and-group> </content-model-expanded> <content-model> <sequence-group> <parament-name name="head.content"/> </sequence-group> </content-model> <inclusions> <or-group> <element-name name="SCRIPT"/> <element-name name="STYLE"/> <element-name name="META"/> <element-name name="LINK"/> <element-name name="OBJECT"/> </or-group> </inclusions> </element> <!-- one such element for every element declared in the DTD --> </dtd> What I want to do is produce, for every element, not only what it's declared content model is (in DTDParse's output file, the content of <content-model-expanded>), but also of any inclusions that apply to the element. And that's where the problem is. If I recall SGML inclusions correctly, an inclusion declared on an element applies to all child elements all the way to the bottom of the relevant part of the document tree. As I understand it, what I need to do is find the parent element(s) of a given element, and see if they have any inclusions; if so, output them. Then, find the parents of that element (or elements) and do the same. And so on. So far I've only done this using <xsl:for-each> and simply moved from one element to its parent(s) and so on: <xsl:template name="trace_ancestor_inclusions"> <xsl:param name="element_name" /> <!-- this changes the context to each parent element of the original element --> <xsl:for-each select="parent::dtd/element[content-model-expanded/descendant::element-name[@name=$element_name]]"> <xsl:variable name="new_element_name" select="@name" /> <p style="padding-left: 20px;">Ancestor Element: <xsl:value-of select="$new_element_name"/><xsl:text> </xsl:text> <xsl:for-each select="inclusions/*"> <xsl:text>( </xsl:text><xsl:apply-templates select="." /><xsl:text> )</xsl:text> </xsl:for-each> </p> <xsl:call-template name="trace_ancestor_inclusions"> <xsl:with-param name="element_name" select="$new_element_name" /> </xsl:call-template> </xsl:for-each> </xsl:template> It seems that what I need is a test around the call-template at the end of the template to test whether I've already encountered a given element and bypass it. If someone could show me what that logic would be, I would be most appreciative. Thanks, Don
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format