Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old January 30th, 2006, 08:05 AM
Registered User
 
Join Date: Jan 2006
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via Yahoo to kanchan_b
Default Some Help

Hey I want to change the following Input XML

<mapping source=”S1234567” startdate="2006/01/18 00:00:00" action=”A”>
   <target product=”T1234” suppliercode=”Supp123” catalogid=”Cat123”>
      <featuredefault name=”Feature1” value=”111”/>
</mapping>

----------------------to
<mapping source=”S1234567” startdate="2006/01/18 00:00:00">
   <keylist>
      <key name=”product.action” value=”A”/>
   </keylist>
   <target product=”T1234” suppliercode=”Supp123” catalogid=”Cat123”>
      <featuredefault name=”Feature1” value=”111”/>
   </target>
</mapping>

Only for the attribute action I need to make an additional child tag <keylist> and forward the other tags as it is .The other attributes of mapping should also be forwarded .

I have written the following xslt but , the value of action is not getting populated and other attributes of <mapping > decared after action are not carried forward .

XSLT------------
 <xsl:template match="@*|node()">
   <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
   </xsl:copy>
</xsl:template>
    <xsl:template match="mapping/@action">
           <keylist>
              <key name= "product.action" >
                    <xsl:attribute name="value">
                 <xsl:value-of select= "mapping/@action"/>
              </xsl:attribute>
              </key>
          </keylist>
          <xsl:apply-templates/>

    </xsl:template>


Please send me back ur suggestions.
Thanks in advance
Kanchan
 
Old January 30th, 2006, 02:52 PM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

If I've understood correctly you need something like:
Code:
<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="mapping">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <keylist>
        <key name="product.action" value="{@action}"/>
      </keylist>
      <xsl:apply-templates select="*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="mapping/@action"/>
--

Joe (Microsoft MVP - XML)
 
Old January 31st, 2006, 03:42 AM
Registered User
 
Join Date: Jan 2006
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via Yahoo to kanchan_b
Default

Thanks for ur solution .

But there are small issue with it .

My requirements
1) I want to add the child tag <Keylist> only if the attribute action exists on <mapping>.
2)If it exist then the <keylist> child tag should be added and the attribute action should be deleted from <mapping>

In other words . The attribute @action will be replaced by following structure and other attributes are retained as in orginal

<keylist>
 <key name="product.action" value="Cease"/>
</keylist>


I have tried modifiying my XSLT but the problem with that is .
It retains all the attribute which occur before action in the output file after transformation and removes off all occuring after action.

MY XSLT -
<xsl:template match="mapping/@action">
  <keylist>
   <key name= "product.action" >
   <xsl:attribute name="value">
   <xsl:value-of select= "."/>
   </xsl:attribute>
    </key>
   </keylist>
 <xsl:apply-templates />
</xsl:template>
------------------------------------------------
Input File
<mapping source="S4" type ="F" action="M" startdate="2006/01/18" >
  <target product="10" suppliercode="2020" catalogid="Goods">
     <featuremaps id="2020:Mobile"/>
     <featuredefaults id="2020:Mobile"/>
  </target>
</mapping>
--------------------------------------------------
Output File
<mapping source="S4" type="F">
  <keylist>
    <key name="product.action" value="M"/>
  </keylist>
  <target product="10" suppliercode="2020" catalogid="Goods">
     <featuremaps id="2020:Mobile"/>
     <featuredefaults id="2020:Mobile"/>
  </target>
</mapping>
-----------------------------------------------------
As you see the @type was retained as in input but @startdate was not .

Awaiting ur response. Thanks in advance .

cheers
Kanchan

 
Old January 31st, 2006, 05:18 AM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

Well if you'd specified the requirements first time...
Code:
<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="mapping">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:if test="@action">
        <keylist>
          <key name="product.action" value="{@action}"/>
        </keylist>
      </xsl:if>
      <xsl:apply-templates select="*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="mapping/@action"/>
--

Joe (Microsoft MVP - XML)
 
Old January 31st, 2006, 05:38 AM
Registered User
 
Join Date: Jan 2006
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via Yahoo to kanchan_b
Default


!!! Thanks a million

Cheers
Kanchan:D

 
Old January 31st, 2006, 07:10 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

I can't see any reason why the attributes before @action should be treated differently from those after. You didn't post the full stylesheet that showed this effect, but on the face of it, it looks like a bug in your XSLT processor (which one are you using?). But if Joe's solution works, then you probably want to move on rather than helping the vendor improve their product...

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old January 31st, 2006, 08:24 AM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

Michael, always willing to learn from the master, is there a more elegant solution?



--

Joe (Microsoft MVP - XML)
 
Old January 31st, 2006, 08:50 AM
Registered User
 
Join Date: Jan 2006
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via Yahoo to kanchan_b
Default

I am using XMLSPY for the transformation.

THe entire XSLT which i used previously
----------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

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


  <xsl:template match="mapping/@action">
    <keylist>
          <key name="product.action" >
      <xsl:attribute name="value">
      <xsl:value-of select= "."/>
      </xsl:attribute>
          </key>
        </keylist>
  </xsl:template>
  </xsl:stylesheet>
----------------------------------------------------------------

Please let me know your take on this.

Cheers
Kanchan:)

 
Old January 31st, 2006, 09:17 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Ah, I see what's going on.

Saxon reports this:

Error at xsl:copy on line 6 of file:/c:/temp/test.xsl:
  XTDE0410: An attribute node (startdate) cannot be created after the children of the containing element

The stylesheet is creating attributes for an element after it creates child elements. An XSLT 1.0 processor is allowed to silently recover from this error by simply not writing these attributes. This is apparently what XML Spy is doing. To get round this you have to process the @action attribute after processing all the others.


Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old February 1st, 2006, 01:24 AM
Registered User
 
Join Date: Jan 2006
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via Yahoo to kanchan_b
Default

Thanks Joe and Micheal for your inputs.

Can you tell me How do I retain the format/indentation in the output xml.
By format I means .)Comments .)Line Breaks .)Tabs

Currently the comment line is shifting one line up.
I need this for clear visibility and for verifying the transformations.

Thanks
Kanchan













Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.