Home. 
.

transparent

transparent

transparent

Altova Mailing List Archives


RE: [xsl] Copy element content to another nested empty element

From: "Michael Kay" <mike@------------>
To:
Date: 5/1/2008 2:57:00 PM
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


transparent
Print
Mail
Like It
Disclaimer
.

These Archives are provided for informational purposes only and have been generated directly from the Altova mailing list archive system and are comprised of the lists set forth on www.altova.com/list/index.html. Therefore, Altova does not warrant or guarantee the accuracy, reliability, completeness, usefulness, non-infringement of intellectual property rights, or quality of any content on the Altova Mailing List Archive(s), regardless of who originates that content. You expressly understand and agree that you bear all risks associated with using or relying on that content. Altova will not be liable or responsible in any way for any content posted including, but not limited to, any errors or omissions in content, or for any losses or damage of any kind incurred as a result of the use of or reliance on any content. This disclaimer and limitation on liability is in addition to the disclaimers and limitations contained in the Website Terms of Use and elsewhere on the site.

.
.

transparent

transparent