Re: [xsl] Adding an element to a list of similar elements?

Subject: Re: [xsl] Adding an element to a list of similar elements?
From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx>
Date: Sun, 6 Apr 2008 18:41:27 +0530
Here's another idea to implement this ...

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                       version="1.0">

 <xsl:output method="xml" indent="yes" />

 <xsl:param name="to_add" />

 <xsl:template match="/cruisecontrol">
   <cruisecontrol>
     <xsl:copy-of select="node()" />
     <project.fullbuild name="{$to_add}" buildAfterFailed="false" />
   </cruisecontrol>
 </xsl:template>

</xsl:stylesheet>

On Sat, Apr 5, 2008 at 9:37 AM, Dan Stromberg <dstromberglists@xxxxxxxxx> wrote:
>
>  This feels incredibly simple - the sort of thing that should be in 62
> different web-based XSLT tutorials, but I've been googling for quite a while
> now, and I don't see much (anything) on the topic.  This is about my 5th
> XSLT script, so I'm more than a bit of a newb.
>
>  All I want to do is add an element to an xml document after a bunch of
> similar elements - hopefully with just one attribute changed relative to the
> similar line before it, or with a skeletal element if there isn't a similar
> element already in the file.  I'm willing to do xpath queries to list what's
> in the file now, and run one or another XSLT script depending on what kind
> of change is needed, using some other language like bash or python to
> control which XSLT kicks in.
>
>  I'm starting to feel like I should ignore XSLT and use a DOM-based Python
> script, but hopefully this list can save me from that (mostly because I
> believe it'd toast the comments, and I like comments :) .
>
>  I have a basic XML document I'm testing with (it comes from cruisecontrol,
> a java-based automated build system) :
>
>  <?xml version="1.0"?>
>  <cruisecontrol>
>   <project.mergeanddelete.dist name="db" buildAfterFailed="false"/>
>   <project.mergeanddelete.dist name="DScripts" buildAfterFailed="false">
>       <property name="log.mergedir" value="checkout/DScripts/dist"/>
>   </project.mergeanddelete.dist>
>   <project.fullbuild name="3.1.2-dev" buildAfterFailed="false"/>
>   <project.fullbuild name="3.1.3-dev" buildAfterFailed="false"/>
>  </cruisecontrol>
>
>  And I just want to add <project.fullbuild name="3.1.4-ga"
> buildAfterFailed="false"/> after <project.fullbuild name="3.1.3-dev"
> buildAfterFailed="false"/> ideally using the 3.1.3-dev line as a template
> for the new 3.1.4 line.
>
>  I experimented a bunch on my own with matching the last() project.fullbuild
> and trying to output two elements on it instead of one, but that seems to be
> going nowhere despite too many variations and machinations to count (you
> don't want to see all the things I tried - too much for the list).  Is this
> at all a reasonable approach in standard XSLT?  After more googling, I saw
> something saying that you shouldn't try to add attributes after a child, and
> I'm not sure if I was running afoul of that or not.  I just kept getting the
> last() element nicely, and then a new element with empty attributes - not
> much in the way of a helpful error message, not even with --verbose.
>
>  Here's -one- of the many things I tried based on this approach:
>
>  <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>   <xsl:template match="node() | @*">
>     <xsl:copy>
>        <xsl:apply-templates select="node() | @*" />
>     </xsl:copy>
>   </xsl:template>
>   <xsl:template match="/cruisecontrol/project.fullbuild[last()]">
>     <xsl:copy>
>        <xsl:copy-of select="node() | @*"/>
>     </xsl:copy>
>     <xsl:text>&#xA;    </xsl:text>
>     <xsl:element name="project.fullbuild">
>        <xsl:attribute name="name" value="${to_add}"/>
>     </xsl:element>
>   </xsl:template>
>  </xsl:stylesheet>
>
>  That {$to_add} is coming from a --string-param on the command line - but
> I'm not even getting a proper name attribute -  it comes out a null string.
>
>  I'm using xsltproc on an openSUSE 10.3 system:
>
>  $ links -dump /tmp/t.html | sed '/^ *$/d'
>   XSL version: 1.0
>   Vendor: libxslt
>   Vendor URL: http://xmlsoft.org/XSLT/
>   Product name: [Undefined]
>   Product version: [Undefined]
>   Is schema-aware: [Undefined]
>   Supports serialization: [Undefined]
>   Supports backwards compatibility: [Undefined]
>
>  $ xsltproc --version
>  Using libxml 20630, libxslt 10120 and libexslt 813
>  xsltproc was compiled against libxml 20630, libxslt 10120 and libexslt 813
>  libxslt 10120 was compiled against libxml 20630
>  libexslt 813 was compiled against libxml 20630
>
>  Help me, Obi-Wan Kenobi... :)
>
>  TIA!


-- 
Regards,
Mukul Gandhi

http://gandhimukul.tripod.com/
http://mukulgandhi.blogspot.com/

Current Thread