[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: an xsl transformation is missing an element from i

Subject: Re: an xsl transformation is missing an element from its output
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Tue, 27 May 2008 16:15:59 -0400
Re:  an xsl transformation is missing an element from i
Hi Tony,

At 02:32 PM 5/27/2008, you wrote:
<?xml version="1.0" encoding="UTF-8"?>
       <ptr target="a" n="2"/>
       <ptr target="b" n="15"/>
       <ptr target="c" n="72"/>
       <ptr target="d" n="3822"/>
       <ptr target="e" n="3823"/>

Here is my stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="no" encoding="utf-8" media-type="text/xml"
doctype-public="-//TEI P4//DTD Main Document Type//EN"/>

   <xsl:template match="@*|node()">
           <xsl:apply-templates select="@*|node()"/>

<xsl:template match="div1"> <xsl:for-each select="ptr"> <xsl:element name="ptr"> <xsl:attribute name="target" select="@target"/> <xsl:attribute name="n" select="position()"/> </xsl:element> </xsl:for-each> </xsl:template>


When I run the transformation, here is the output I get:

<?xml version="1.0" encoding="utf-8"?><test>
   <ptr target="a" n="1"/><ptr target="b" n="2"/>
   <ptr target="c" n="1"/><ptr target="d" n="2"/><ptr target="e" n="3"/>

All attributes within the ptr element are exactly as I want them. But
I also want to preserve the div1 element tags in the output. Why are
they not showing up, and how can I get the desired result?

They aren't showing up because they are being matched by a template that says to process their ptr element children, but doesn't say to do anything with the div1 elements themselves.

You could effect this by adding an xsl:copy instruction to your template:

<xsl:template match="div1">
    <xsl:copy-of select="@*"/>
    <xsl:for-each select="ptr">
      <xsl:element name="ptr">
        <xsl:attribute name="target" select="@target"/>
        <xsl:attribute name="n" select="position()"/>

But an even cleaner solution would match not on the div1 but on the ptr elements, since those are the elements you wish to modify:

<xsl:template match="ptr">
  <ptr target="{@target}" n="{count(.|preceding-sibling::ptr)}"/>


* Instead of using the xsl:attribute instruction, attributes are created in a literal result element using the attribute value template syntax (curly braces) to provide the values. This is more succinct.
* To generate the value for @n, instead of using the position of the current node in the current node list (which works when you nest in the for-each, but which depends on your traversal logic and so is prone to break when things get more complex), this simply counts the ptr plus its preceding sibling ptr elements, assigning @n by the count.
* The div1 elements will still be copied if you leave the generic "identity template" in place (which says to copy it if it isn't matched by another template, which it now isn't).

Congratulations on your first stylesheet. You're getting the idea.


Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
  Mulberry Technologies: A Consultancy Specializing in SGML and XML

Current Thread


Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
First Name
Last Name
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.