[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] RE: Flattening a tree
Thank you very much for your answer. It helps me understanding the way the things work. However, the first solution is not flat enough and the second one is too flat ! In the second case, all the elements are treated the same and everything is flattened. In the first case, the result is : <document> content-1 <Item>content-2</Item> <Item>content-3</Item> content-4 <graphic/> content-5 </document> This takes off the tags but does not really flatten the structure. At this point, I cannot think of something else than hiding the "inline" tags, applying the second template (or Mike's one), and then unhiding the inline tags. This is a bit complicated and should involve several pass, somme being non-xsl, but I can't think of any better solution. Thanks again. Pierre-Yves -----Message d'origine----- De : owner-xsl-list@xxxxxxxxxxxxxxxx [mailto:owner-xsl-list@xxxxxxxxxxxxxxxx]De la part de Jeni Tennison Envoyé : vendredi 14 juillet 2000 12:45 À : Pierre-Yves Saumont Cc : XSL-List@xxxxxxxxxxxxxxxx Objet : Re: Flattening a tree Pierre-Yves, >Does anyone know how it would be possible to transform a (sub)tree into a >flat list of some of its elements (those considered not "inline"), mixing >cdata and subelements. Just to expand on Mike's solution a little, here are two templates that operate in 'flatten mode'. The first matches any element. If it is an element that contains subelements, then it simply applies templates (again in flatten mode) on its children (both elements and text, if there is any). If it is an element that does not contain any subelements - in other words a #PCDATA element or an EMPTY element - then it makes a copy of itself. <xsl:template match="*" mode="flatten"> <xsl:choose> <xsl:when test="*"><xsl:apply-templates mode="flatten" /></xsl:when> <xsl:otherwise> <xsl:copy-of select="." /> </xsl:otherwise> </xsl:choose> </xsl:template> The second template matches any text node and (so long as it isn't empty), places its (normalised) content into an element with the name of its parent element (as in Mike's solution). <xsl:template match="text()" mode="flatten"> <xsl:if test="normalize-space(.) != ''"> <xsl:element name="{name(..)}"> <xsl:value-of select="normalize-space(.)" /> </xsl:element> </xsl:if> </xsl:template> So, to flatten the content of a particular element, apply templates in flatten mode on its children. In your example: <xsl:template match="document"> <document> <xsl:apply-templates mode="flatten" /> </document> </xsl:template> This gives the result you wanted in SAXON. I hope that helps, Jeni Dr Jeni Tennison Epistemics Ltd, Strelley Hall, Nottingham, NG8 6PE Telephone 0115 9061301 ? Fax 0115 9061304 ? Email jeni.tennison@xxxxxxxxxxxxxxxx XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|