Subject: [xsl] Text replacement using "recursion" From: TeleServices <teleservices@xxxxxxxxx> Date: Mon, 22 Oct 2007 11:40:10 -0700 |
I have a reporting system that merges three xml sources: 1) boilerplate - text seen in all reports 2) custom - text that is used to replace "phrase" elements in boilerplate 3) vars - values (text or numbers) used to select from custom text This works fine unless I wish to put a "phrase" element inside another "phrase" element. I originally did the "flat" version" with an implication that in future I would allow "recursion" (phrases inside phrases). Well I bit off a little more than I bargained for because I do not seem to understand how to get this type of "recursion" to work. Note, that there are several ways this is used. This can be seen in the examples. I can expound on this if need be - I am trying to keep this very simple to start with. Following my message are example files: 1) boilerplate.xml - For simplicity I have combined boilerplat.xml, custom.xml and vars.xml into this one file - normally they are passed as pararmeters (it get same results). 2a) merge.xsl (original version) - merges the three sources 2b) merge.xsl (attempt at "recursion") - merges the three sources 3) present.xsl - present report.xml as HTML file report.htm to view results as user would see them. I have been using command line tols to test this problem. To create the report.xml file I process these files I am using msxsl.exe under Windows: msxsl boilerplate.xml merge.xsl > report.xml or xsltproc under linux: xsltproc merge.xsl boilerplate.xml >report.xml To present the report.xml as an HTML file report.htm, I use one of these commands. For Windows: msxsl report.xml present.xsl > report.htm for linux: xsltproc present.xsl report.xml >report.htm So, can anyone help me understand how to process a "phrase" inside a "phrase"? Also, any critiques or suggestion about my code are most welcome as I am bit of a newbie. Thanks for any help! Dan Vokt, Teleservices ==== FILES ARE BELOW ====================================== 1) boilerplate, custom, vars: ---- boilerplate.xml ----------------------------------------------------- <?xml version="1.0" encoding="ISO-8859-1"?> <report> <vars> <!-- vars.xml generated at runtime --> <var name="var1">value1</var> <var name="var2">value2</var> <var name="var3">value3</var> <var name="var4">value4</var> </vars> <lists> <!-- custom.xml --> <list name="keyword-list"> <option id="value1">VALUE_1</option> <option id="value2">VALUE_2</option> <option id="value3">VALUE_3</option> <option id="value4">VALUE_4</option> </list> <list name="phrase-list"> <option id="value1">this is phrase list item 1 from phrase-list</option> <option id="value2">this is phrase list item 2 from phrase-list</option> <option id="value3">this is phrase list item 3 from phrase-list</option> <option id="value4">this is phrase list item 4 from phrase-list</option> </list> <list name="phrase-list-recursive"> <option id="value1">this is phrase list item 1 from phrase-list-recursive, with a value of '<phrase name="var1"/>' for var1</option> <option id="value2">this is phrase list item 2 from phrase-list-recursive, with a value of '<phrase name="var1"/>' for var1</option> <option id="value3">this is phrase list item 3 from phrase-list-recursive, with a value of '<phrase name="var1"/>' for var1</option> <option id="value4">this is phrase list item 4 from phrase-list-recursive, with a value of '<phrase name="var1"/>' for var1</option> </list> </lists> <h4>name to value:</h4> <!-- boilerplate.xml --> Your var1 value of <phrase name="var1"/> is very interesting, though not as interesting as the <phrase name="var4"/> value of your var4.<br /> <h4>name to keyword:</h4> Your var1 keyword of <phrase name="var1" list="keyword-list"/> is very interesting, though not as interesting as the <phrase name="var4" list="keyword-list"/> keyword of your var4.<br /> <h4>name to phrase:</h4> Your var1 phrase of <phrase name="var1" list="phrase-list"/> is very interesting, though not as interesting as the <phrase name="var4" list="phrase-list"/> phrase of your var4.<br /> <h4>name to phrase-recursive -- PROBLEM!!!:</h4> Your var1 recursive phrase of <phrase name="var1" list="phrase-list-recursive"/> is very interesting, though not as interesting as the <phrase name="var4" list="phrase-list-recursive"/> recursive phrase of your var4.<br /> </report> -------------------------------------------------------------------------- 2a) Here is the ORIGINAL XSL file that merges these: ---- merge.xsl (original) ------------------------------------------------ <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" encoding="utf-8" indent="yes"/> <xsl:strip-space elements="report"/> <!-- original --> <xsl:template match="phrase"> <span class="phrase"> <xsl:variable name="phrase" select="@name"/> <xsl:variable name="list"> <xsl:choose> <xsl:when test="@list"><xsl:value-of select="@list"/></xsl:when> <xsl:otherwise><xsl:value-of select="@name"/></xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="var" select="//vars/var[@name=$phrase]/text()"/> <xsl:variable name="verbiage" select="//lists/list[@name=$list]/option[@id=$var]"/> <xsl:if test="string-length($verbiage)>0"><xsl:value-of select="$verbiage"/></xsl:if> <xsl:if test="string-length($verbiage)=0"><xsl:value-of select="$var"/></xsl:if> </span> </xsl:template> <xsl:template match="*"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates/> </xsl:copy> </xsl:template> <!-- do not directly process vars or lists --> <xsl:template match="vars"/> <xsl:template match="lists"/> </xsl:stylesheet> -------------------------------------------------------------------------- 2b) Here is my lame ATTEMPT at "recursion": ---- merge.xsl ("recursive") --------------------------------------------- <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" encoding="utf-8" indent="yes"/> <xsl:strip-space elements="report"/> <xsl:template match="phrase"> <xsl:variable name="phrase-name" select="@name"/> <xsl:variable name="list"> <xsl:choose> <xsl:when test="@list"><xsl:value-of select="@list"/></xsl:when> <xsl:otherwise><xsl:value-of select="@name"/></xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="var" select="//vars/var[@name=$phrase-name]/text()"/> <xsl:variable name="verbiage" select="//lists/list[@name=$list]/option[@id=$var]"/> <xsl:variable name="phrase"> <xsl:choose> <xsl:when test="string-length($verbiage)>0"><xsl:value-of select="$verbiage"/></xsl:when> <xsl:otherwise><xsl:value-of select="$var"/></xsl:otherwise> </xsl:choose> </xsl:variable> <span class="phrase"> <xsl:value-of select="$phrase"/> <xsl:if test="//vars/var[@name=$phrase-name]/phrase"> <xsl:apply-templates select="//vars/var[@name=$phrase-name]/phrase"/> </xsl:if> <xsl:if test="//lists/list[@name=$list]/option[@id=$var]/phrase"> <xsl:apply-templates select="//lists/list[@name=$list]/option[@id=$var]/phrase"/> </xsl:if> </span> </xsl:template> <xsl:template match="*"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates/> </xsl:copy> </xsl:template> <!-- do not directly process vars or lists --> <xsl:template match="vars"/> <xsl:template match="lists"/> </xsl:stylesheet> -------------------------------------------------------------------------- 3) I present the report.xml as an HTML file report.htm using this: ---- present.xsl --------------------------------------------------------- <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes" encoding="utf-8"/> <xsl:template match="/"> <html> <head> <title>Simple Recursive Phrase</title> <style> p { margin-top: 0; } h4 { margin-bottom: .5em; } .phrase { color:blue; } .phrase .phrase { color:red; } .phrase .phrase .phrase { color:green; } .phrase .phrase .phrase .phrase { color:magenta; } </style> </head> <body><xsl:apply-templates/></body> </html> </xsl:template> <xsl:template match="para"> <xsl:if test="@title!=''"> <h4 class="paratitle"><xsl:value-of select="@title"/></h4> </xsl:if> <p><xsl:apply-templates/></p> </xsl:template> <xsl:template match="a|ul|li|img|table|tr|td|span|div|pre|label|h4"> <xsl:copy><xsl:copy-of select="@*"/> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="br"><br /></xsl:template> </xsl:stylesheet> --------------------------------------------------------------------------
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Newbie: Extracting and ev, Michael Kay | Thread | Re: [xsl] Date, Number Format, cknell |
Re: [xsl] Converting base64 back to, Tony Lavinio | Date | [xsl] Date, Number Format, Waqar Ali |
Month |