Subject: RE: [xsl] Copy element content to another nested empty element From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Thu, 1 May 2008 15:56:10 +0100 |
I think your basic problem is here: <xsl:template match="phrase"> <xsl:variable name="phrase" select="@name"/> <xsl:variable name="list" select="@list"/> <span class="phrase"><xsl:value-of select="//lists/list[@name=$list]/option[@id=$phrase]"/></span> </xsl:template> You are taking the "value-of" an option element (which flattens it to a string), but the option element actually has internal structure that needs to be further processed. So try this instead: <xsl:template match="phrase"> <xsl:variable name="phrase" select="@name"/> <xsl:variable name="list" select="@list"/> <span class="phrase"> <xslapply-templates select="//lists/list[@name=$list]/option[@id=$phrase]"/> </span> </xsl:template> I haven't tested this, but it should be the only change you need to make. Except that if your data contains cycles, your code will probably blow up with a "stack full" error. Michael Kay http://www.saxonica.com/ > -----Original Message----- > From: TeleServices [mailto:teleservices@xxxxxxxxx] > Sent: 01 May 2008 15:38 > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > Subject: [xsl] Copy element content to another nested empty element > > I am just getting started with XML/XSLT and I struggle > sometimes with the non-procedural thinking required (I am > used to plain old "C" > programming). > > What I am trying to do is take the content of a selected > element (node from "lists) and copy it into another nested > empty "phrase" element. > The empty element references the "list" element using "name" > and "list" attributes. Here is a tiny example of the source: > > <?xml version="1.0" encoding="utf-8"?> > <report> > <lists> > <list name="phrase-list1"> > <option id="value1">a simple phrase</option> > <option id="value2">also a simple phrase</option> > <option id="value3">could be a simple phrase</option> > <option id="value4">another simple phrase</option> > </list> > <list name="phrase-list2"> > <option id="value1">a compound phrase element with what > '<phrase name="value3" list="phrase-list1"/>' (single quotes) > inside</option> > <option id="value2">the compound phrase element > containing '<phrase name="value4" list="phrase-list1"/>' > (single quotes)</option> > <option id="value3">multi-compound phrases with '<phrase > name="value1" list="phrase-list1"/>' and '<phrase name="value4" > list="phrase-list1"/>' or more</option> > <option id="value4">a compound compound phrase element > with "<phrase name="value2" list="phrase-list2"/>" (double > quotes)</option> > </list> > </lists> > > <h4>Simple Phrases</h4> > The first phrase element is <phrase name="value1" > list="phrase-list1"/>. And the second phrase element is > <phrase name="value2" list="phrase-list1"/>, and the third > phrase element <phrase name="value3" list="phrase-list1"/> as well. > <h4>Compound Phrases</h4> > Things get tricky though when instead of <phrase name="value1" > list="phrase-list1"/>, we have <phrase name="value1" > list="phrase-list2"/> of it. We could have <phrase name="value3" > list="phrase-list2"/> inside of it. We could even have > <phrase name="value4" list="phrase-list2"/> in a nested fashion. > </report> > > The XSLT I am using works for "top level" (non-nested) > elements but I just cannot seem to grasp how to get this to > work with the nested elements. I have a vague notion that I > should be dealing with node sets here, but this is at the > edge of my current understanding. Here is the simple > (non-working) XSLT: > > <?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="/report"> > <html> > <head> > <title>Phrase Insertion</title> > <style> > .phrase {background:yellow;} > .phrase .phrase {background:cyan;} > .phrase .phrase .phrase {background:magenta;} > </style> > </head> > <body> > <xsl:apply-templates/> > </body> > </html> > </xsl:template> > > <!-- insert phrases --> > <xsl:template match="phrase"> > <xsl:variable name="phrase" select="@name"/> > <xsl:variable name="list" select="@list"/> > <span class="phrase"><xsl:value-of > select="//lists/list[@name=$list]/option[@id=$phrase]"/></span> > </xsl:template> > > <!-- pass other elements --> > <xsl:template match="*"> > <xsl:copy> > <xsl:copy-of select="@*"/> > <xsl:apply-templates/> > </xsl:copy> > </xsl:template> > > <!-- do not directly process lists --> > <xsl:template match="lists"/> > </xsl:stylesheet> > > The match="phrase" template is the culprit. I have tried > apply-templates in a few different ways, but I cannot seem to > get at the nested "phrases". > > Here is the current (non-working) output: > > <?xml version="1.0" encoding="utf-8"?> > <html> > <head> > <title>Phrase Insertion</title> > <style> > .phrase {background:yellow;} > .phrase .phrase {background:cyan;} > .phrase .phrase .phrase {background:magenta;} > </style> > </head> > <body> > <h4>Simple Phrases</h4> > The first phrase element is <span class="phrase">a simple > phrase</span>. And the second phrase element is <span > class="phrase">also a simple phrase</span>, and the third > phrase element <span class="phrase">could be a simple > phrase</span> as well. > <h4>Compound Phrases</h4> > Things get tricky though when instead of <span > class="phrase">a simple phrase</span>, we have <span > class="phrase">a compound phrase element with what '' (single > quotes) inside</span> of it. We could have <span > class="phrase">multi-compound phrases with '' and '' or > more</span> inside of it. We could even have <span > class="phrase">a compound compound phrase element with "" > (double quotes)</span> in a nested fashion. > </body> > </html> > > NOTE: I have added a little CSS formatting to make it easy to > see the copied content. Here is what I would like to produce: > > <?xml version="1.0" encoding="utf-8"?> > <html> > <head> > <title>Phrase Insertion</title> > <style> > .phrase {background:yellow;} > .phrase .phrase {background:cyan;} > .phrase .phrase .phrase {background:magenta;} > </style> > </head> > <body> > <h4>Simple Phrases</h4> > The first phrase element is <span class="phrase">a simple > phrase</span>. And the second phrase element is <span > class="phrase">also a simple phrase</span>, and the third > phrase element <span class="phrase">could be a simple > phrase</span> as well. > <h4>Compound Phrases</h4> > Things get tricky though when instead of <span > class="phrase">a simple phrase</span>, we have <span > class="phrase">a compound phrase element with what '<span > class="phrase">could be a simple phrase</span>' > (single quotes) inside</span> of it. We could have <span > class="phrase">multi-compound phrases with '<span > class="phrase">a simple phrase</span>' and '<span > class="phrase">another simple phrase</span>' or more</span> > inside of it. We could even have <span class="phrase">a > compound compound phrase element with "<span > class="phrase">the compound phrase element containing '<span > class="phrase">another simple phrase</span>' (single quotes)</span>" > (double quotes)</span> in a nested fashion. > </body> > </html> > > If you copy and paste the two htm sections into files and > view with a browser it is very clear what I am getting versus > what I am trying to produce. > > As I said I am thinking that I need to process this using > nodesets, but at this point "my reach exceeds my grasp", so > if anyone can help me understand the "trick" to dealing with > the nested elements I would appreciate it greatly. I have > searched this mailing list and the web in general but I > cannot not seem to find anything to help me in this matter. > > Thanks in advance for any help... > > > -Kiel
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Copy element content to anoth, TeleServices | Thread | RE: [xsl] Copy element content to a, TeleServices |
Re: [xsl] xsltproc/LibXSLT - non-co, Manfred Staudinger | Date | Re: [xsl] Problem with Safari?, Manfred Staudinger |
Month |