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 April 18th, 2011, 10:44 AM
Authorized User
 
Join Date: Apr 2008
Posts: 85
Thanks: 10
Thanked 0 Times in 0 Posts
Default Recreating the XML

Hi All,
I want to reproduce xml using xslt, if there are multiple record of the same 'Name' element
then in the new XML only single record should appear which has latest Modify time.

Example XML
===========
Code:
<Display>
   <Results>
     <Result>
        <ModifyDate>20110412</ModifyDate>
        <ModifyTime>161144</ModifyTime>
        <Name>Test.txt</Name>
     </Result>
     <Result>
        <ModifyDate>20110412</ModifyDate>
        <ModifyTime>161211</ModifyTime>
        <Name>Test.txt</Name>
     </Result>
      <Result>
        <ModifyDate>20110310</ModifyDate>
        <ModifyTime>140502</ModifyTime>
        <Name>Usert.doc</Name>
     </Result>
   </Results>
</Display>
Want to produce below xml.
Desired XML
===========
Code:
<Display>
   <Results>     
     <Result>
        <ModifyDate>20110412</ModifyDate>
        <ModifyTime>161211</ModifyTime>
        <Name>Test.txt</Name>
     </Result>
      <Result>
        <ModifyDate>20110310</ModifyDate>
        <ModifyTime>140502</ModifyTime>
        <Name>Usert.doc</Name>
     </Result>
   </Results>
</Display>
Could someone please give some hint how to achieve this.

Thanks
-Nelly
 
Old April 19th, 2011, 06:16 AM
Authorized User
 
Join Date: Apr 2008
Posts: 85
Thanks: 10
Thanked 0 Times in 0 Posts
Default

Could someone please shed some light on it....or give some hint please.

Thanks
Nelly
 
Old April 19th, 2011, 06:56 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Do you want to use XSLT 2.0 or 1.0? With 2.0 you can simply group with for-each-group and then take the max date and/or time (I am not sure what you want).
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old April 19th, 2011, 07:26 AM
Authorized User
 
Join Date: Apr 2008
Posts: 85
Thanks: 10
Thanked 0 Times in 0 Posts
Default

Hi Martin,

Thank you very much for your reply. I want to use XSLT 2.0.

If you could provide some example code that will reply helpful.

Thanks Again
-Nelly
 
Old April 19th, 2011, 07:34 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Here is a sample, it groups using for-each-group, then sorts based on the provided date and time to take the item with latest date/time:
Code:
<xsl:stylesheet version="2.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="Results">
  <xsl:copy>
    <xsl:for-each-group select="Result" group-by="Name">
      <xsl:for-each select="current-group()">
        <xsl:sort select="ModifyDate + ModifyTime" order="descending"/>
        <xsl:if test="position() eq 1">
          <xsl:apply-templates select="."/>
        </xsl:if>
      </xsl:for-each>
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old April 19th, 2011, 10:22 AM
Authorized User
 
Join Date: Apr 2008
Posts: 85
Thanks: 10
Thanked 0 Times in 0 Posts
Default

Hi Martin

I am getting error on the below line on the ','

<xsl:apply-templates select="@*, node()"/>

It should be '|' instead of ',' or something else?

Thanks
Nelly
 
Old April 19th, 2011, 10:35 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

You can use
select="@* | node()"
if you want or need to but the comma should work with any compliant XSLT 2.0 processor.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old April 19th, 2011, 10:45 AM
Authorized User
 
Join Date: Apr 2008
Posts: 85
Thanks: 10
Thanked 0 Times in 0 Posts
Default

Thanks Martin for your reply.

I am using .net's 'System.Xml.Xsl.XslTransform(); and came to know that It doesn't support XSLT 2.0.

Could you please give some hint what is the alternate of the 2.0 in 1.0.

What changes I need to do to work with xslt 1.0.

Inestead of 'xsl:for-each-group' what can I use to achieve that.

Thanks
-Nelly
 
Old April 19th, 2011, 10:50 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

With XSLT 1.0 you need to use Muenchian grouping instead of the for-each-group, grouping in XSLT 1.0 is described on http://www.jenitennison.com/xslt/grouping/index.xml.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old April 19th, 2011, 12:45 PM
Authorized User
 
Join Date: Apr 2008
Posts: 85
Thanks: 10
Thanked 0 Times in 0 Posts
Default

Hi Martin,

I am trying with the below XSLT but not getting proper result:

Code:
 
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheetxmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" version="1.0">
<xsl:key name="Results-by-name" match="contact" use="Name"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Display">
<Display>
<xsl:apply-templates/>
</Display>
</xsl:template><xsl:template match="Results">
<xsl:copy>
<Results>
<xsl:apply-templates select="Result"></xsl:apply-templates>
</Results></xsl:copy>
</xsl:template><xsl:template match="Result"><xsl:for-each select="Result[count(. | key('Results-by-name', Name)[1]) = 1]"><xsl:for-each select="key('Results-by-name', Name)">
<xsl:sort select="OTModifyDate + OTModifyTime" order="descending"/><xsl:apply-templates select="."/></xsl:for-each></xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Regards
Yunus





Similar Threads
Thread Thread Starter Forum Replies Last Post
Split xml file with result document and javax.xml.transform.Transformer. nisargmca XSLT 3 January 12th, 2010 06:26 AM
After recreating database on my Host Server, do I .... Ali Ezz BOOK: Beginning ASP.NET 3.5 : in C# and VB BOOK ISBN: 978-0-470-18759-3 1 January 3rd, 2010 06:58 AM
VB.net, adding XML data to an existing XML file saikoboarder XML 11 April 17th, 2008 04:19 PM
E-mailing InfoPath Forms & Recreating XML Data... bburnsid Infopath 0 January 22nd, 2007 05:13 PM
recreating propertygrid using listview ken_kapchan BOOK: Professional C#, 2nd and 3rd Editions 0 March 22nd, 2004 05:48 AM





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