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 March 1st, 2013, 01:50 AM
Registered User
 
Join Date: Feb 2013
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hello,

i want to use xslt 2.0

Thanks in advance.

Last edited by roychan; March 1st, 2013 at 02:07 AM..
 
Old March 1st, 2013, 06:15 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

With XSLT 2.0 you can group with for-each-group and then create a result-document for each group:
Code:
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

<xsl:output indent="yes"/>

<xsl:template match="receipt">
  <xsl:for-each-group select="prod/(carrier, person)" group-by="@id">
    <xsl:result-document href="receipt_{current-grouping-key()}.xml">
      <receipt>
         <prod>
           <xsl:copy-of select="../(* except (carrier, person)), current-group()"/>
         </prod>
      </receipt>
    </xsl:result-document>
  </xsl:for-each-group>
</xsl:template>

</xsl:stylesheet>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old March 4th, 2013, 08:45 AM
Registered User
 
Join Date: Feb 2013
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks Martin, its working fine.
To its extension if i have person tag inside someother tag say <persondetails>

xml:
<?xml version="1.0" encoding="UTF-8"?>
<receipt>
<manufacturer>1</manufacturer>
<manufacturer_gln/>
<transfer_recipt/>
<prod>
<product_GTIN/>
<product_LOT/>
<production_date/>
<expire_date/>
<carrier id="123">
<carrier_type>1</carrier_type>
</carrier>

<carrier id="456">
<carrier_type>1</carrier_type>
</carrier>
<personaldetails>
<person id="123">
<fn>Life</fn>
</person>
<person id="456">
<fn>Life1</fn>
</person>
</personaldetails>
</prod>
</receipt>

then can i use <xsl:for-each-group > ??
because i have tried it but i'm not able to get it.
 
Old March 4th, 2013, 08:52 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Well with the changed input format you as well need to explain what output format you want, then I am sure there is a way to adapt the posted for-each-group solution.

So post a sample of the format you want for the result files and then we can help changing the XSLT.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old March 4th, 2013, 10:34 AM
Registered User
 
Join Date: Feb 2013
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Input xml:

<receipt>
<manufacturer>1</manufacturer>
<manufacturer_gln/>
<transfer_recipt/>
<prod>
<product_GTIN/>
<product_LOT/>
<production_date/>
<expire_date/>
<carrier id="123">
<carrier_type>1</carrier_type>
</carrier>
<carrier id="234">
<carrier_type>2</carrier_type>
</carrier>
<carrier id="456">
<carrier_type>3</carrier_type>
</carrier>
<personaldetails>
<person id="123">
<fn>fn1</fn>
</person>
<person id="234">
<fn>fn2</fn>
</person>
<person id="456">
<fn>fn3</fn>
</person>
</personaldetails>
</prod>
</receipt>

by grouping id's of person,carrier.. i want the output something like this

file1.xml

<receipt>
<manufacturer>1</manufacturer>
<manufacturer_gln/>
<transfer_recipt/>
<prod>
<product_GTIN/>
<product_LOT/>
<production_date/>
<expire_date/>
<carrier id="123">
<carrier_type>1</carrier_type>
</carrier>
<personaldetails>
<person id="123">
<fn>fn1</fn>
</person>
</personaldetails>
</prod>
</receipt>

file2.xml
<receipt>
<manufacturer>1</manufacturer>
<manufacturer_gln/>
<transfer_recipt/>
<prod>
<product_GTIN/>
<product_LOT/>
<production_date/>
<expire_date/>
<carrier id="234">
<carrier_type>1</carrier_type>
</carrier>
<personaldetails>
<person id="234">
<fn>fn2</fn>
</person>
</personaldetails>
</prod>
</receipt>

file3.xml

<receipt>
<manufacturer>1</manufacturer>
<manufacturer_gln/>
<transfer_recipt/>
<prod>
<product_GTIN/>
<product_LOT/>
<production_date/>
<expire_date/>
<carrier id="456">
<carrier_type>1</carrier_type>
</carrier>
<personaldetails>
<person id="456">
<fn>fn3</fn>
</person>
</personaldetails>
</prod>
</receipt>


thanks in advance..
 
Old March 4th, 2013, 11:26 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Here is an adjusted stylesheet:
Code:
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="receipt">
  <xsl:for-each-group select="prod/(carrier, personaldetails/person)" group-by="@id">
    <xsl:result-document href="receipt_{current-grouping-key()}.xml">
      <receipt>
         <prod>
           <xsl:copy-of select="../(* except (carrier, personaldetails)), current-group()[self::carrier]"/>
           <xsl:apply-templates select="current-group()[self::person]"/>
         </prod>
      </receipt>
    </xsl:result-document>
  </xsl:for-each-group>
</xsl:template>

<xsl:template match="person">
  <personaldetails>
    <xsl:copy-of select="."/>
  </personaldetails>
</xsl:template>

</xsl:stylesheet>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old March 5th, 2013, 10:16 AM
Registered User
 
Join Date: Feb 2013
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hello Martin,

Its working fine.. Thank you so much.. I want to learn xslt with xpath , i would be very grateful if you could provide me some urls so that i can go through it.
 
Old March 5th, 2013, 10:34 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Roychan,

You might find this URL useful:

http://www.wrox.com/WileyCDA/Section/XML.id-105067.html

;-)

Michael Kay
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
 
Old March 6th, 2013, 05:11 AM
Registered User
 
Join Date: Feb 2013
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hey Hi Martin,

but if i change the input xml as

<receipt>
<manufacturer>1</manufacturer>
<manufacturer_gln/>
<transfer_recipt/>
<prod>
<product_GTIN/>
<product_LOT/>
<production_date/>
<expire_date/>
<carrier id="123">
<carrier_type>1</carrier_type>
</carrier>
<carrier id="234">
<carrier_type>2</carrier_type>
</carrier>
<carrier id="456">
<carrier_type>3</carrier_type>
</carrier>
<personaldetails>
<person id="123" perid="1">
<fn>fn1</fn>
</person>
<person id="123" perid="2">
<fn>fn2</fn>
</person>
<person id="123" perid="3">
<fn>fn3</fn>
</person>
<person id="234" perid="4">
<fn>fn4</fn>
</person>
<person id="234" perid="5">
<fn>fn5</fn>
</person>
<person id="456" perid="6">
<fn>fn3</fn>
</person>
</personaldetails>
</prod>
</receipt>


with the following xslt

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">

<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="receipt">
<xsl:for-each-group select="prod/(carrier, personaldetails/person)" group-by="@id">
<xsl:result-document href="receipt_{current-grouping-key()}.xml">
<receipt>
<prod>
<xsl:copy-of select="../(* except (carrier, personaldetails)), current-group()[self::carrier]"/>
<xsl:apply-templates select="current-group()[self::person]"/>
</prod>
</receipt>
</xsl:result-document>
</xsl:for-each-group>
</xsl:template>

<xsl:template match="person">
<personaldetails>
<xsl:copy-of select="."/>
</personaldetails>
</xsl:template>

</xsl:stylesheet>

the output should look something like this

file1.xml

<receipt>
<manufacturer>1</manufacturer>
<manufacturer_gln/>
<transfer_recipt/>
<prod>
<product_GTIN/>
<product_LOT/>
<production_date/>
<expire_date/>
<carrier id="123">
<carrier_type>1</carrier_type>
</carrier>
<personaldetails>
<person id="123" perid="1">
<fn>fn1</fn>
</person>
<person id="123" perid="2">
<fn>fn2</fn>
</person>
<person id="123" perid="3">
<fn>fn3</fn>
</person>
</personaldetails>
</prod>
</receipt>

file2.xml


<receipt>
<manufacturer>1</manufacturer>
<manufacturer_gln/>
<transfer_recipt/>
<prod>
<product_GTIN/>
<product_LOT/>
<production_date/>
<expire_date/>
<carrier id="234">
<carrier_type>2</carrier_type>
</carrier>
<personaldetails>
<person id="234" perid="4">
<fn>fn4</fn>
</person>
<person id="234" perid="5">
<fn>fn5</fn>
</person>
</personaldetails>
</prod>
</receipt>

<receipt>
<manufacturer>1</manufacturer>
<manufacturer_gln/>
<transfer_recipt/>
<prod>
<product_GTIN/>
<product_LOT/>
<production_date/>
<expire_date/>
<carrier id="456">
<carrier_type>3</carrier_type>
</carrier>
<personaldetails>
<person id="456" perid="6">
<fn>fn3</fn>
</person>
</personaldetails>
</prod>
</receipt>

but i'm not able to get the output like this.. Is it possible to get the output like this. If yes,then how should i adjust the above xslt

Thanks!!
 
Old March 6th, 2013, 06:20 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

I will show you some further adjustment but these forums a "programmer to programmer" forums where are you supposed to ask for help if you are able to apply the suggestions made and adapt them for your needs yourself.
With the latest variation of the input with several "person" elements of the same "id" you want to group I think that
Code:
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="receipt">
  <xsl:for-each-group select="prod/(carrier, personaldetails/person)" group-by="@id">
    <xsl:result-document href="receipt_{current-grouping-key()}.xml">
      <receipt>
         <prod>
           <xsl:copy-of select="../(* except (carrier, personaldetails)), current-group()[self::carrier]"/>
           <personaldetails>
              <xsl:copy-of select="current-group()[self::person]"/>
           </personaldetails>
         </prod>
      </receipt>
    </xsl:result-document>
  </xsl:for-each-group>
</xsl:template>

</xsl:stylesheet>
should do the job.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog





Similar Threads
Thread Thread Starter Forum Replies Last Post
Split large XML to smalls nzvtvsky9 XSLT 1 January 13th, 2010 01:48 PM
Split xml file with result document and javax.xml.transform.Transformer. nisargmca XSLT 3 January 12th, 2010 06:26 AM
Regarding xml-html transformation of an xml string using xslt and javascript suprakash444 XSLT 1 January 12th, 2009 01:23 AM
Convert 1 big XML to multiple smaller XML victorcorey XSLT 1 March 20th, 2008 05:59 AM
XSLT for complicated xml to xml transf. required doug@sirvisetti XSLT 3 June 17th, 2005 04:26 PM





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