Subject: Re: [xsl] repeat and replace loop ( at the same time ) From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Tue, 2 Apr 2002 16:41:45 +0100 |
Hi PG, > I need to repeat an XML record and replace it at the same time with > different data. In your example, the driver for the number of times that you want to "repeat" the record is 'replace_data.xml'. Since you're working with two documents, I recommend that you create global variables to hold the relevant nodes of each -- the record elements: <xsl:variable name="template" select="/root/record" /> <xsl:variable name="data" select="document('replace_data.xml')/root/record" /> You should then apply templates to the record elements from 'replace_data.xml', as you are doing: <xsl:template match="/"> <root> <xsl:apply-templates select="$data" /> </root> </xsl:template> The template for the record needs to basically copy the template record, but using the information from the current record. The template needs to match record elements and create a record element: <xsl:template match="record"> <record> ... </record> </xsl:template> For the content of the record, you need to process the content of the template record element, but in doing so, the processor needs to be aware of the data from the current record. You could store it in a variable, and then iterate over the content of the template, with something like: <xsl:template match="record"> <record> <xsl:variable name="record" select="." /> <xsl:for-each select="$template/namedcell"> ... </xsl:for-each> </record> </xsl:template> Or you could apply templates to the content of the template, passing the record as a parameter, with something like: <xsl:template match="record"> <record> <xsl:apply-templates select="$template/*"> <xsl:with-param name="record" /> </xsl:apply-templates> </record> </xsl:template> <xsl:template match="data" /> <xsl:template match="namedcell"> <xsl:param name="record" /> ... </xsl:template> Either way, you then need to copy the current namedcell element: <xsl:copy-of select="." /> And then you need to identify the relevant child element of the record element, named by current namedcell element. You can find this by getting all the child elements of the record and then filtering that node set to retrieve only those whose name is the same as the name attribute of the current node, with: $record/*[name() = current()/@name] Assuming that you want to copy the existing data element if there is no such element, you could use something like: <xsl:variable name="value" select="$record/*[name() = current()/@name]" /> <xsl:choose> <xsl:when test="$value"> <data><xsl:value-of select="$value" /></data> </xsl:when> <xsl:otherwise> <xsl:copy-of select="following-sibling::data[1]" /> </xsl:otherwise> </xsl:choose> How you actually handle the content of the template is up to you, of course. The principal of working with separate template and data is: - process the data to provide the repetition - process the template to provide the structure - process the data to provide the values Getting from the data to the template to the data again means keeping track of where you are, which you can do with variables or parameters. Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] repeat and replace loop ( at , progressdll linux | Thread | Re: [xsl] repeat and replace loop (, Jeni Tennison |
[xsl] repeat and replace loop ( at , progressdll linux | Date | Re: [xsl] Keep two FO rows together, David B. Bitton |
Month |