Subject: [xsl] More Multi-Document Mambo From: Larry Garfield <lgarfiel@xxxxxxxxxxxxxxxxxxx> Date: Wed, 18 Jul 2001 01:44:33 -0500 |
Thanks again to David for his help. I'm still a bit curious about how exactly multi-document trees interact. Suppose I have a simple XML file, source.xml: <source> <title>A source file</title> <body> <section> <title>Hello World!</title> <para>Some stuff</para> <para>More stuff</para> </section> <section> <title>Hello Universe!</title> <para>Some stuff</para> <para>More stuff</para> </section> <section> <title>Hello Voices Everywhere!</title> <para>Some stuff</para> <para>More stuff</para> <footer> <para>Evil stuff</para> <evilsection> <para>Bad stuff</para> <para>More bad stuff</para> </evilsection> <footer> </section> </body> </source> And I have another file, template.xml: <output> <head> <author>Larry</author> <insert:title /> </head> <main> <insert:body /> </main> </output> (Yes, this is a very simple and stupid example, I just want to illustrate what I'm trying to do and simplify it conceptually so that I can wrap my brain around it.) I want to have an XSLT sheet that transforms source.xml into multiple output files that are based on the template via insertions. I'm using a technique presented in an article on xml.com a while back that someone posted here (http://www.xml.com/pub/a/2000/07/26/xslt/xsltstyle.html), combined with engine-specific output redirection to create a separate file for each <section>. The XSLT file begins like: <xsl:stylesheet> <!-- various attributes omitted for the moment for simplicity --> <xsl:variable name="sourcefile" select="/" /> <xsl:variable name="template" select="document('template.xml')" /> <xsl:template match ="/"> <xsl:for-each select="//section"> <xsl:variable name="sectNum" select="position()" /> <xsl:variable name="sectFile">sect<xsl:value-of select="position()" />.xml</xsl:variable> <redirect:write href="$sectFile"> <xsl:apply-templates select="$template/html/*"> <xsl:with-param name="sectNum"><xsl:value-of select="$sectNum" /></xsl:with-param> </xsl:apply-templates> </redirect:write> </xsl:for-each> </xsl:template> <xsl:template match ="insert:title"> <xsl:param name="sectTitle"/> <newtitle> <xsl:apply-templates select="$sourcefile/source/body/section[position()=$sectNum]/title" /> </newtitle> </xsl:template> <xsl:template match ="insert:body"> <xsl:param name="sectTitle"/> <!-- Point A --> <xsl:apply-templates select="$sourcefile/source/body/section[position()=$sectNum]" /> </xsl:template> <xsl:template match="para"> <!-- Point B --> <p><xsl:apply-templates /></p> </xsl:template> <!-- Identity transformation --> <xsl:template match="@*|*|text()"> <xsl:param name="sectTitle"/> <xsl:copy> <xsl:apply-templates select="@*|node()|text()"> <xsl:with-param name="sectNum"><xsl:value-of select="$sectNum" /></xsl:with-param> </xsl:apply-templates> </xsl:copy> </xsl:template> </xsl:stylesheet> OK, so far, so good. Assuming I retyped all of that right (I'm going from memory of the files I'm working with), when this stylesheet is applied to the source.xml file, it will loop over each <section> tag and call the template tree on it for each separate output. That part is working. The identity transformation will pass through the contents of the template untouched, passing the current section number along, until it gets to <insert:title />, which will be caught by the other template. That template will catch <insert:title /> and should call back out to the source tree for the value of the title of this section. However, it is returning NULL when I run it. That's question number one. Question number two involves the evil contents of the <footer> tag in the original source.xml file. I do not want the contents of <footer> to be present in the result files at all. Normally the default rule would pass it through without copying it into the result tree (just its textual content), but here the identity transformation, necessary for the template file, catches it and passes it through as is. So my final output file has bits and pieces of untransformed source hanging around in it. In the actual project I'm working on, there are too many such nodes to have a specific null rule for each one, it would be unfeasible. Which brings me to generalized question number three, which is, in the above example, what precisely is happening with the separate trees, and how can I differentiate between a node that originated in one tree as opposed to the other? At <!-- Point A --> above, the ancestor path would be source/body/section/output/main/insert:body, by my reading. So when I call apply-templates, and eventually get to <!-- Point B -->, the ancestor path would be source/body/section/output/main/insert:body/section/para. That means that when it hits the footer, both of the two root nodes (<source> and <output>) are in its ancestor path, so I cannot put a test into the identity transformation to determine which tree it is part of, as they are now the same tree. Am I making any sense here? :-) I suppose what I want to do boils down to having two separate default templates (one identity, one null) based on which root node a given element originates from, regardless of the crisscrossed path by which the processor got there. Is that even possible? Is my interpretation of what is going on correct? Thanks in advance for any information anyone can provide. -- Larry Garfield lgarfiel@xxxxxxxxxxxxxxxxxxx Do you have a PalmOS Organizer? Click here to add me to your address book: http://signature.coola.com/?lgarfiel@xxxxxxxxxxxxxxxxxxx -- "If at first you don't succeed, skydiving isn't for you." :-) XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] fill in a table with dyna, Rene de Vries | Thread | Re: [xsl] More Multi-Document Mambo, David Carlisle |
[xsl] fill in a table with dynamic , Jan Weiss | Date | [xsl] Any Recommended XSL integrate, Ben Leighton |
Month |