Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > XML > XSLT
Password Reminder
Register
| FAQ | Members List | Search | Today's Posts | Mark Forums Read
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
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old April 27th, 2007, 09:28 PM
Registered User
 
Join Date: Apr 2007
Location: , , .
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
Default Generic & Dynamic XSLT but small problem..help

Hi All,

I am new to XSLT. I used Stylus studio Enterprise to see if I can generate XSLT code from source and targe XML. I can see that it does generate, but it hardcodes the elements and node names, which i do not want. The entire XSLT has to be generic and dynamically create the outpuyt XML....
I would appreciate if you guys can help me in creating a XSLT file from my input and output XML.
The input XML is like this, I have reduced the XML tags, but they can be varying, so our XSLT has to be dynamic
<?xml version="1.0" encoding="UTF-8" ?>
 <ns0:MT_UPDATEPERSONAVARIANTS xmlns:ns0="urn:sd:sales:sapvarianttablestopersona" >
 <CallProc>
 <Update_Persona_Variants action="EXECUTE">
  <table>Edit_stored_proc</table>
  <CoverTextLocation type="CHAR">MC</CoverTextLocation>
  <AlbumType type="CHAR">163</AlbumType>
   </Update_Persona_Variants>
  </CallProc>
 <CallProc>
 <Update_Persona_Variants action="EXECUTE">
  <table>abcd_procedure</table>
  <CoverTextLocation type="CHAR">MC</CoverTextLocation>
  <AlbumType type="CHAR">100</AlbumType>
  </Update_Persona_Variants>
  </CallProc>
</ns0:MT_UPDATEPERSONAVARIANTS>

My output XML should be like this
<?xml version="1.0" encoding="UTF-8"?>
<ns0:MT_Generic xmlns:ns0="urn:sd:sales:genericcall">
<CallProc>
<wrapper action="EXECUTE">
<table>xi_wrap</table>
<p1 type = "VARCHAR">Edit_stored_proc</p1>
<p2 type = "VARCHAR">@CoverTextLocation = MC | @AlbumType = 163</p2>
</wrapper>
</CallProc>
<CallProc>
<wrapper action="EXECUTE">
<table>xi_wrap</table>
<p1 type = "VARCHAR">abcd_procedure</p1>
<p2 type = "VARCHAR">@CoverTextLocation = MC | @AlbumType = 100</p2>
</wrapper>
</CallProc>
</ns0:MT_Generic>
I came up with following XSLT, but the output is not as expected. The second line attributes(albumtype 100 and covertextloc MC get concated with the first <p2> tag. The second <p2> tag looks same as first. What is wrong here. Kindly help

<xsl:template match="/">
        <ns0:MT_Generic xmlns:ns0="urn:sd:sales:genericcall">
            <xsl:for-each select="//CallProc">
                <CallProc>
                    <wrapper action="EXECUTE">
                        <table>xi_wrap</table>
                        <p1 type="VARCHAR">
                        <xsl:value-of select="//table"/>
                        </p1>
                        <p2 type="VARCHAR">
                        <xsl:for-each select="//table/following-sibling::node()">
                        <xsl:value-of select="concat('@',name(),' = ')"/>
                        <xsl:value-of select="concat(text(),'|')"/>
                        </xsl:for-each>
                        </p2>
                    </wrapper>
                </CallProc>
            </xsl:for-each>
        </ns0:MT_Generic>
    </xsl:template>

I want (key = value) pairs extracted from source XML to be plugged in the p2 tag. This process has to be generic as source XML can have varying number of tags, means in the example i have give there are 2 tags(albumtype, covertextlocation), but it can go to 12 or 18 or 30 tags. I can give you one thing to start with, the action attribute and table element is always there in all input XMLs. You cannot use MT_UPDATEPERSONAVARIANTS, Update_Persona_Variants and if possible CallProc(though i used, i would like XSLT without it) in XSLT as they keep changing in each XML. I do not know how to use those descendent, sibling ,etc. tags, but i think this complex scenario is possible in XSLT.
Though i am a very good programmer in SAP, XSLT has beaten me. Since last 3 days I am trying to learn and implent this, but struggling. I would greatly appreciate your inputs. Thanks in advance

Reply With Quote
  #2 (permalink)  
Old April 28th, 2007, 03:10 AM
joefawcett's Avatar
Wrox Author
Points: 9,763, Level: 42
Points: 9,763, Level: 42 Points: 9,763, Level: 42 Points: 9,763, Level: 42
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Exeter, , United Kingdom.
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

Well I think your main problem is not understanding context and using paths that start with // all the time which find all the nodes matching, not just the ones underneath the context node. But to help I would need to know the mapping better. If you cannot rely on CallProc what can you rely on, is the structure the same but the elements are named differently or can elements be missing altogether, e.g. does there have to be an element instead of <Update_Persona_Variants action="EXECUTE">? There is a sample XSLT below.
Code:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <ns0:MT_Generic xmlns:ns0="urn:sd:sales:genericcall">
      <xsl:apply-templates select="*/*"/>
    </ns0:MT_Generic>
  </xsl:template>
  <xsl:template match="/*/*">
    <xsl:element name="{name()}">
      <wrapper action="{*/@action}">
        <table>xi_wrap</table>
        <p1 type="VARCHAR">
          <xsl:value-of select="*/table"/>
        </p1>
          <p2 type="VARCHAR">
            <xsl:apply-templates select="*/table/following-sibling::*"/>
          </p2>
      </wrapper>
    </xsl:element>
  </xsl:template>

  <xsl:template match="*">
    <xsl:value-of select="concat('@', name())"/>
    <xsl:text> = </xsl:text>
    <xsl:value-of select="."/>
    <xsl:if test="position() != last()"> | </xsl:if>
  </xsl:template>
</xsl:stylesheet>
As a side point the resulting XML is a lot harder to process than the input, once you start concatenating elements into string values it becomes much harder to work with the data.

--

Joe (Microsoft MVP - XML)
Reply With Quote
  #3 (permalink)  
Old April 28th, 2007, 03:25 AM
mhkay's Avatar
Wrox Author
Points: 18,487, Level: 59
Points: 18,487, Level: 59 Points: 18,487, Level: 59 Points: 18,487, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

>if I can I can generate XSLT code from source and targe XML

In my experience this only works for very simple mappings, more or less renaming and projection. For anything more complex, writing the code by hand is easier.

I'm not sure why you're generating this rather strange output XML. It seems to contain an odd mixture of data and code. Wouldn't it be better to generate an XSLT stylesheet? Either way, if you're generating anything containing XPath expressions, you need to think quite hard about getting the namespaces to work.

As Joe points out, your basic error is that you've thrown in gratuitous calls on "//" all over the place. This might suggest that what you're attempting is a bit ambitious for your current level of skill/knowledge/experience.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #4 (permalink)  
Old April 29th, 2007, 05:42 PM
Registered User
 
Join Date: Apr 2007
Location: , , .
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks Joe, this is awesome. Your XSLT works. Basically instead of CallProc, the name can be something different, namespace, tags almost everything is different in each XML(except table tag and action attribute). Though I am not able to understand your template match piece, i feel good as it works..::). I will try to debug and understand what is going on in your XSLT.

Thanks to you also Mike. To answer your question, i am doing this to call an Oracle or MS SQL stored procedure from SAP XI. XI sends an XML file to the database driver, which then converts the XML to database specific SQL statement. When you call a stored procedure the sequence of parameters should be passed in exactly the same way they are defined in the stored procedure at the database side.
 What I am trying to achieve, is to eliminate the need for parameters to be in sequence. I have created a wrapper stored procedure, which will parse the parameters and send to any stored procedure by matching the sequence even if i have not passed in proper sequence.

  I will take first XML, manipulate it with this XSLT and the newly generated XML i will pass to the SAP database driver.

  Thanks again to you guys. You guys are kings in XSLT.


Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
help to create dynamic listbox using xslt & JS kramsengg XSLT 7 June 10th, 2008 05:00 AM
XPath & XSLT problem Andy-7M XSLT 7 May 3rd, 2007 02:50 AM
dynamic xslt -> xslt creation namespace problem jkmyoung XSLT 2 July 15th, 2006 12:42 AM
Templates & Generic Programming shazia1 VS.NET 2002/2003 0 March 29th, 2006 12:13 PM
Creaing Dynamic generic Cust ID srichary BOOK: Beginning ASP 3.0 3 November 9th, 2004 08:54 AM



All times are GMT -4. The time now is 11:28 PM.


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