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 July 29th, 2010, 09:44 AM
Registered User
 
Join Date: Jul 2010
Posts: 6
Thanks: 2
Thanked 0 Times in 0 Posts
Default Generate and Use UniqueId at two places in target XML

Hello All,

I need develop a XSLT and below is input and target. when the LocationId is mapped to target XML in StopDetails , need to generate a Unique Id for StopId, we have developed a custom Xpath function that would return unique ID so we are good until this part..But the problem is , the stop location needs to mapped to LineItems as well, when doing so, we need to map the same unique id generated above for the StopId..In the Target XML, these stop and lineietms elements are not in sequence, they are at different levels..so I need some kind of storing mechanism to store the UniqueId generated for Stops and use them same at LineItem level. I am not getting any thoughts on how to achieve this, Would appreciate your help on this.

Input XML

<Shipment>
<Stops>
<Stop>
<LocationId>XYZ123</LocationId>
</Stop>
<Stop>
<LocationId>XYZ345</LocationId>
</Stop>
<Stop>
<LocationId>XYZ567</LocationId>
</Stop>
</Stops>
</Shipment>

Target XML

<Root-element>
<StopDetails>
<Stop>
<StopId>111</StopId>
<LocationId>XYZ123</LocationId>
</Stop>
<Stop>
<StopId>112</StopId>
<LocationId>XYZ345</LocationId>
</Stop>
<Stop>
<StopId>113</StopId>
<LocationId>XYZ567</LocationId>
</Stop>
</StopDetails>
<!-- Many element here -->
<LineItems>
<Lineitem>
<id>item1</id>
<Stopdetails>
<Stop>
<StopId>111</StopId>
<LocationId>XYZ123</LocationId>
</Stop>
<Stop>
<StopId>112</StopId>
<LocationId>XYZ345</LocationId>
</Stop>
</Stopdetails>
</Lineitem>
<Lineitem>
<id>item2</id>
<Stopdetails>
<Stop>
<StopId>112</StopId>
<LocationId>XYZ345</LocationId>
</Stop>
<Stop>
<StopId>113</StopId>
<LocationId>XYZ567</LocationId>
</Stop>
</Stopdetails>
</Lineitem>
</LineItems>
</Root-element>


Thanks/Steve
 
Old July 29th, 2010, 09:54 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

One way would be to use generate-id() on the LocationId element to generate the unique identifier. But it you need control over the identifiers generated, change your function so it takes the LocationId as a parameter, and either hashes it, or remembers the values previously generated in a hashmap or similar.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
 
Old July 29th, 2010, 09:54 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

If you need to process the same elements twice (as you seem to do with Stop/LocationId) then I would expect you to achieve that using modes on your templates. And if you already have a function that computes an id I don't see why you can't call that function in templates with different modes.
Or what exactly prevents you from calling that function at different places in your stylesheet?
Of course if needed you could (at least with XSLT 2.0) easily do the first processing/mapping in a variable value and then process the contents of that variable where you already have the generated id. That might also need modes however.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old July 29th, 2010, 10:00 AM
Registered User
 
Join Date: Jul 2010
Posts: 6
Thanks: 2
Thanked 0 Times in 0 Posts
Default

The Xpath function invokes a database sequence so i cannot call the same function twice as it would return a different value. the business wants these Ids to be in sequence so we decided to use a DB sequence.
 
Old July 29th, 2010, 10:12 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Do you use XSLT 2.0? Or XSLT 1.0 and your XSLT processor supports an extension function like exsl:node-set to convert a result tree fragment into a node-set? Then I think my second suggestion should do e.g.
Code:
<xsl:template match="/">
  <xsl:variable name="temp1">
     <xsl:apply-templates select="Shipment/Stops"/>
     <!-- create StopDetails with those templates, callng your function -->
  </xsl:variable>
  
  <Root-element>
    <xsl:copy-of select="$temp1/StopDetails"/>
    <!-- then process the variable here to create line items e.g. -->
    <xsl:apply-templates select="$temp1/StopDetails"/>
  </Root-element>
</xsl:template>

<xsl:template match="Shipment/Stops">
  <StopDetails>
    <xsl:apply-templates/>
  </StopDetails>
</xsl:template>

<xsl:template match="Shipment/Stops/Stop">
  <xsl:copy>
     <StopId><xsl:value-of select="foo:your-function()"/></StopId>
     <xsl:copy-of select="LocationId"/>
  </xsl:copy>
</xsl:template>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old July 29th, 2010, 11:10 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

>The Xpath function invokes a database sequence so i cannot call the same function twice

In a functional language, that's bad news. Turn it into a memo function by checking if it's been called before for a given argument, and if so, returning the same value.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference





Similar Threads
Thread Thread Starter Forum Replies Last Post
Number with 2 decimal places only pallone SQL Server 2000 4 July 3rd, 2007 07:29 AM
Display Decimal Places rsm42 ASP.NET 1.0 and 1.1 Basics 3 January 7th, 2007 10:46 AM
Two decimal places only pallone Javascript How-To 5 February 2nd, 2005 12:35 AM
output only 2 decimal places Toka1 Javascript How-To 2 February 20th, 2004 11:44 AM





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