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 August 30th, 2012, 08:05 PM
Registered User
 
Join Date: Nov 2011
Posts: 5
Thanks: 1
Thanked 0 Times in 0 Posts
Default Using Intermediate variables in XSLT

This must be a quickie for Experts but i'm finding it bit difficult to code the logic.

Input

<RetrieveCustomersRequest>
<additionalCriteria>
<ifw2:searchExpression>
<ifw2:fieldName>SortCode</ifw2:fieldName>
<ifw2:fieldValue>222222</ifw2:fieldValue>
</ifw2:searchExpression>
<ifw2:searchExpression>
<ifw2:fieldName>CustomerProductIdentifier</ifw2:fieldName>
<ifw2:fieldValue>111119</ifw2:fieldValue>
</ifw2:searchExpression>
<ifw2:searchExpression>
<ifw2:fieldName>SMMBusinessName</ifw2:fieldName>
<ifw2:fieldValue>333333</ifw2:fieldValue>
</ifw2:searchExpression>
<ifw2:searchExpression>
<ifw2:fieldName>SMMPartyId</ifw2:fieldName>
<ifw2:fieldValue>444444</ifw2:fieldValue>
</ifw2:searchExpression>
</additionalCriteria>
</RetrieveCustomersRequest>

XSLT

<xsl:variable name="fieldName" select="/*[local-name()='Envelope']/*[local-name()='Body']/*[local-name()='RetrieveCustomersRequest']/*[local-name()='additionalCriteria']/*[local-name()='searchExpression']/*[local-name()='fieldName']"/>

<ocis:F148Request>
<xsl:if test="$fieldName">
<xsl:for-each select="$fieldName">
<xsl:if test="starts-with(.,'Sort')">
<ocis:SortCd/>
<xsl:value-of select="following-sibling::*[.]"/>
<ocis:SortCd/>
</xsl:if>
<xsl:if test="starts-with(.,'Customer')">
<ocis:ExtProdHeldIdTx>
<xsl:value-of select="following-sibling::*[.]"/>
</ocis:ExtProdHeldIdTx>
</xsl:if>
<xsl:if test="starts-with(.,'SMM')">
<ocis:SMMData>
<xsl:if test="starts-with(.,'SMMBusinessName')">
<ocis:BusinessNm>
<xsl:value-of select="following-sibling::*[.]"/>
</ocis:BusinessNm>
</xsl:if>
<xsl:if test="starts-with(.,'SMMPartyId')">
<ocis:PartyId>
<xsl:value-of select="following-sibling::*[.]"/>
</ocis:PartyId>
</xsl:if>
</ocis:SMMData>
</xsl:if>
</xsl:for-each>
</xsl:if>
</ocis:F148Request>

OUTPUT


<ocis:F148Request>
<ocis:SortCd/>222222<ocis:SortCd/>
<ocis:ExtProdHeldIdTx>111119</ocis:ExtProdHeldIdTx>
<ocis:SMMData>
<ocis:BusinessNm>333333</ocis:BusinessNm>
</ocis:SMMData>
<ocis:SMMData>
<ocis:PartyId>444444</ocis:PartyId>
</ocis:SMMData>
</ocis:F148Request>

As you see the output above, <ocis:SMMData> group is being repeated because of instruction <xsl:for-each select="$fieldName">. But the desired output should like below..BusinessNm and PartyId should be grouped under SMMData section.

Desired Output

<ocis:F148Request>
<ocis:SortCd/>222222<ocis:SortCd/>
<ocis:ExtProdHeldIdTx>111119</ocis:ExtProdHeldIdTx>
<ocis:SMMData>
<ocis:BusinessNm>333333</ocis:BusinessNm>
<ocis:PartyId>444444</ocis:PartyId>
</ocis:SMMData>
</ocis:F148Request>

I have tried using Intermediate varaibles within for-each and write the output outside the logic but couldn't do so...Is there any easy way to code to the get the output in the desired way?

Thanks for the help.
 
Old August 31st, 2012, 04:24 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

It's a grouping problem, and like all grouping problems it's easy in XSLT 2.0 and tricky in XSLT 1.0. You don't say which you are using.

You also don't explain your requirements very well. If the only grouping you need to do is to group the fields whose names start with SMM, then that's fairly easy: just do something like this:

Code:
<xsl:apply-templates select="searchExpression[not(starts-with(ifw2:fieldName, 'SMM'))]"/>
<ocis:SMMData>
  <xsl:apply-templates select="searchExpression[starts-with(ifw2:fieldName, 'SMM')]"/>
</ocis:SMMData>

<xsl:template match="searchExpression[starts-with(ifw2:fieldName, 'Sort')]">
<ocis:sortCD><xsl:value-of select="ifw2:fieldData"/></ocis:sortCD>
</xsl:template>
etc.

Note that splitting the code into template rules like this will make it much more understandable and maintainable than a monilithic xsl:for-each with lots of conditionals.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference

Last edited by mhkay; August 31st, 2012 at 04:28 AM..





Similar Threads
Thread Thread Starter Forum Replies Last Post
Refer variables from XSLT Include or Import chilly XSLT 1 July 26th, 2010 09:56 AM
beginning to intermediate to professional. shegxzyl PHP FAQs 1 May 14th, 2009 10:49 AM
intermediate storage sarah lee ASP.NET 1.0 and 1.1 Basics 3 September 11th, 2006 01:31 PM
XSLT: Joining params with Variables shasto100 XSLT 2 April 24th, 2006 07:15 AM
variables in xslt will.richardson XSLT 1 September 24th, 2003 01:23 AM





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