xsl-list
[Top] [All Lists]

Re: xslt adds elements twice in xml.

2005-02-17 15:42:51
On Thu, 17 Feb 2005 12:38:13 -0800, Nishi Bhonsle
<nishi(_dot_)bhonsle(_at_)oracle(_dot_)com> wrote:
Hi:

I have the following xml snippet:
<portlet logLevel="error">
<enablePortlet status="true"></enablePortlet>
<sessionPool maxSessions="20" useCachedSession="true"
maxSessionAgeHour="1" maxSessionInactivityPeriodMinute="10"></sessionPool>
</portlet>

I need to write a xsl which transforms the above xml to the following xml--

<portlet logLevel="error" pickerCompatibleVersions="10.1.2"
maxDataRows="1000" logLevel="error">
<enablePortlet status="true"/>
<sessionPool maxSessions="20" useCachedSession="true"
maxSessionAgeHour="35" maxSessionInactivityPeriodMinute="17"
maxRefreshWaitMinute="1" maxRefreshRetries="1" maxGenericParameters="10"
maxNewSessionPerMinute="6" maxWaitNewSessionMinute="30"/>
</portlet>

I'm not sure where the additional attributes for the sessionPool originate.  


I wrote the following, but it adds the enablePortlet element and the
sessionPool element twice in the resultant file --

Given the xslt below, you should get something along these lines
(modified whitespace fore easier reading):

<?xml version="1.0" encoding="UTF-8"?>
<portlet           pickerCompatibleVersions="10.1.2" 
                     maxDataRows="1000" logLevel="error">

<sessionPool  maxRefreshWaitMinute="1" 
                      maxRefreshRetries="1"           
                      maxGenericParameters="10"/>
</portlet>
<enablePortlet status="true"/>

Usually when I see "doubling" it is actually the text node being
printed out because I  do not have template for that particular
element but it is called directly in another template.  Should be
plenty in the FAQ about that (check identity transformations or text
nodes).  However, I don't see any text nodes in the input.  Are there
any other templates?



<xsl:template match="portlet">
<xsl:copy>
<xsl:attribute
name="pickerCompatibleVersions"><xsl:text>10.1.2</xsl:text></xsl:attribute>
<xsl:attribute name="maxDataRows"><xsl:text>1000</xsl:text></xsl:attribute>
<xsl:copy-of select="@*"/>

<xsl:element name="sessionPool">
<xsl:attribute
name="maxRefreshWaitMinute"><xsl:text>1</xsl:text></xsl:attribute>
<xsl:attribute
name="maxRefreshRetries"><xsl:text>1</xsl:text></xsl:attribute>
<xsl:attribute
name="maxGenericParameters"><xsl:text>10</xsl:text></xsl:attribute>
</xsl:element>
<xsl:apply-templates/>
</xsl:copy>
<xsl:copy-of select="enablePortlet"/>
</xsl:template>

What am I doing wrong in the xslt? Can someone please help.

It's hard to tell without seeing what your output is, but I have some
gut feelings.  First, why the copy of the portlet element?  Is there
some reason you cannot do the following?

<xsl:template match="portlet">
<xsl:element name="portlet">
<xsl:attribute
name="pickerCompatibleVersions"><xsl:text>10.1.2</xsl:text></xsl:attribute>
<xsl:attribute name="maxDataRows"><xsl:text>1000</xsl:text></xsl:attribute>
<xsl:copy-of select="@*"/>
.....


Also notice that xsl:copy-of select="enablePortlet" is outside of the
copy.  This means it'll be copied outside of the portlet element (if I
remember correctly).  Do you need to use one template?  Instead, I'd
recommend that you break this up into three, like so:

<?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"/>

<xsl:template match="portlet">
  <xsl:element name="portlet">
    <xsl:attribute
name="pickerCompatibleVersions"><xsl:text>10.1.2</xsl:text></xsl:attribute>
    <xsl:attribute name="maxDataRows"><xsl:text>1000</xsl:text></xsl:attribute>
    <xsl:copy-of select="@*"/>

    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

<xsl:template match="sessionPool">
  <xsl:element name="sessionPool">
    <xsl:attribute
      name="maxRefreshWaitMinute"><xsl:text>1</xsl:text></xsl:attribute>
    <xsl:attribute
      name="maxRefreshRetries"><xsl:text>1</xsl:text></xsl:attribute>
    <xsl:attribute
      name="maxGenericParameters"><xsl:text>10</xsl:text></xsl:attribute>
    <xsl:copy-of select="@*"/>
  </xsl:element>
  
</xsl:template>

<xsl:template match="enablePortlet">
  <xsl:copy-of select="."/>
</xsl:template>


</xsl:stylesheet>

Notice if the order of the document is important you'll want to just
use the one template or the three templates but using call-template.

Jon Gorman

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--