i have folowing XML structure:
<root>
<product>
<name>
<book1>data for book1</book1>
<book12>data for book12</book12>
<book13>data for book13</book13>
<book14>data for book14</book14>
</name>
<info>
<data1>data for data1</data1>
<data2>data for data2</data2>
<data3>data for data3<data3>
<data4>data for data4</data4>
<data5>data for data5</data5>
<data n+1>data n+1</data n+1>
</info>
<pictures>
<pic1>data for pic1</pic1>
<pic2>data for pic2</pic2>
<pic3>data for pic3</pic3>
<pic4>data for pic4</pic4>
<pic n+1>data for pic n+1</pic n+1>
</pictures>
</product>
<product>
.
.
.
.
.
</product>
.
.
.
.
</root>
Now i would need to copy data5, book14 and whole node pictures within every node product so output xml would look like this:
<root>
<product>
<node_that_i_would_name_1>
<node_that_i_would_name_2>
<node_that_i_would_name_3>
<node_that_i_would_name_4>
<book14>data for book14</book14>
</node_that_i_would_name_4>
<node_that_i_would_name_5>
<data5>data for data5</data5>
</node_that_i_would_name_5>
<picturesA>
<pic1A>
<pic2A>
<pic3A>
<pic4A>
<pic n+1A>
</picturesA>
<empty_node_at_the_end_that_i_will_name></empty_node_at_the_end_that_i_will_name>
</node_that_i_would_name_3>
</node_that_i_would_name_2>
</node_that_i_would_name_1>
<name>
<book1>data for book1</book1>
<book12>data for book12</book12>
<book13>data for book13</book13>
<book14>data for book14</book14>
</name>
<info>
<data1>data for data1</data1>
<data2>data for data2</data2>
<data3>data for data3<data3>
<data4>data for data4</data4>
<data5>data for data5</data5>
<data n+1>data n+1</data n+1>
</info>
<pictures>
<pic1>data for pic1</pic1>
<pic2>data for pic2</pic2>
<pic3>data for pic3</pic3>
<pic4>data for pic4</pic4>
<pic n+1>data for pic n+1</pic n+1>
</pictures>
</product>
<product>
.
.
.
.
.
</product>
.
.
.
.
</root>
Every thing should stay the same, only this data would have to be copyed and rearenged in way above into nodes. Is there simple way to do this with xslt?
When you ever see a problem like this, your first thought should be the Identity Transform
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
All this does by itself is simply copy all existing nodes to the output document. But what this means is that you then only have to write templates for any particular element you wish to transform, in your case the product element. (XSLT will give priority to templates that match a specific node name over the more generic match used by the identity template).
So, the template for product would have this structure. Essentially it is still the identity transform but with extra code thrown in.
<xsl:template match="product">
<xsl:copy>
<xsl:apply-templates select="@*" />
<!-- Code to create new nodes and create extra copies of existing ones goes here -->
<xsl:apply-templates select="node()"/>
</xsl:copy>
EDIT: Note that attributes need to be copied across before any elements!
For example, to create a copy of the book14 element within a new element, you would simply add this code:
<newnode1>
<xsl:apply-templates select="name/book14"/>
</newnode1>
For the Picture elements, to allow this to be copied with an extra suffix on the element name, you would have a template to match the child elements, with an (optional) parameter which would then be used in creating the element name
<xsl:template match="pictures/*">
<xsl:param name="suffix" />
<xsl:element name="{concat(local-name(), $suffix)}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
This template would then be used in two different places. One where it matches the structure normally, and one where you want to create the extra copy. But in the latter case, you would set the parameter:
<xsl:apply-templates select="pictures/*">
<xsl:with-param name="suffix" select="'A'" />
</xsl:apply-templates>
Try this XSLT as a sample, you should be able to expand on it with those nodes that you really want to name yourself....
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="product">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<newnode>
<newnode1>
<xsl:apply-templates select="name/book14"/>
</newnode1>
<newnode2>
<xsl:apply-templates select="info/data5"/>
</newnode2>
<picturesA>
<xsl:apply-templates select="pictures/*">
<xsl:with-param name="suffix" select="'A'" />
</xsl:apply-templates>
</picturesA>
</newnode>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="pictures/*">
<xsl:param name="suffix" />
<xsl:element name="{concat(local-name(), $suffix)}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>