Flatten nodes that have repeated child node using XSLT -


i have document of following structure (this example me verbalize problem), i'm trying flatten. flattening mean copying <report_entry> nodes several <event>s each <report_entry> node contained single <event>

what have:

<?xml version="1.0"?> <report_data>   <report_entry>     <id>1</id>     <event>       <start_date>2011-09-06</start_date>       <end_date>2011-09-10</end_date>     </event>     <event>       <start_date>2011-09-10</start_date>       <end_date>2011-09-15</end_date>     </event>     <event>       <start_date>2011-09-15</start_date>       <end_date>2011-09-20</end_date>     </event>   </report_entry>   <report_entry>     <id>2</id>     <event>       <start_date>2011-09-20</start_date>       <end_date>2011-09-25</end_date>     </event>     <event>       <start_date>2011-09-25</start_date>       <end_date>2011-09-30</end_date>     </event>   </report_entry>   <report_entry>     <id>3</id>     <event>       <start_date>2011-09-30</start_date>       <end_date>2011-10-05</end_date>     </event>   </report_entry> </report_data> 

what i'm trying get:

<?xml version="1.0"?> <report_data>   <report_entry>     <id>1</id>     <event>       <start_date>2011-09-06</start_date>       <end_date>2011-09-10</end_date>     </event>   </report_entry>   <report_entry>     <id>1</id>     <event>       <start_date>2011-09-10</start_date>       <end_date>2011-09-15</end_date>     </event>   </report_entry>   <report_entry>     <id>1</id>     <event>       <start_date>2011-09-15</start_date>       <end_date>2011-09-20</end_date>     </event>   </report_entry>   <report_entry>     <id>2</id>     <event>       <start_date>2011-09-20</start_date>       <end_date>2011-09-25</end_date>     </event>   </report_entry>   <report_entry>     <id>2</id>     <event>       <start_date>2011-09-25</start_date>       <end_date>2011-09-30</end_date>     </event>   </report_entry>   <report_entry>     <id>3</id>     <event>       <start_date>2011-09-30</start_date>       <end_date>2011-10-05</end_date>     </event>   </report_entry> </report_data> 

here xslt i'm using:

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform">  <xsl:template match="node() | @*">     <xsl:copy>         <xsl:apply-templates select="node() | @*"/>     </xsl:copy> </xsl:template>  <xsl:template match="report_entry">   <xsl:for-each select="event">     <report_entry>       <xsl:copy-of select="../*[not(self::event)]"/>       <xsl:copy-of select="."/>     </report_entry>   </xsl:for-each> </xsl:template>  </xsl:stylesheet> 

it works, though feel there might better, faster , more universal solution. in particular, don't "hardcoding" <report_entry> since way wouldn't able copy attributes (if any). there other ways/templates deal problem?

as simple this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform">  <xsl:output omit-xml-declaration="yes" indent="yes"/>  <xsl:strip-space elements="*"/>   <xsl:template match="/*">   <report_data>     <xsl:apply-templates select="*/event"/>   </report_data>  </xsl:template>   <xsl:template match="event">   <report_entry>    <xsl:copy-of select="../id | ."/>   </report_entry>  </xsl:template> </xsl:stylesheet> 

when transformation applied on provided xml document:

<report_data>   <report_entry>     <id>1</id>     <event>       <start_date>2011-09-06</start_date>       <end_date>2011-09-10</end_date>     </event>     <event>       <start_date>2011-09-10</start_date>       <end_date>2011-09-15</end_date>     </event>     <event>       <start_date>2011-09-15</start_date>       <end_date>2011-09-20</end_date>     </event>   </report_entry>   <report_entry>     <id>2</id>     <event>       <start_date>2011-09-20</start_date>       <end_date>2011-09-25</end_date>     </event>     <event>       <start_date>2011-09-25</start_date>       <end_date>2011-09-30</end_date>     </event>   </report_entry>   <report_entry>     <id>3</id>     <event>       <start_date>2011-09-30</start_date>       <end_date>2011-10-05</end_date>     </event>   </report_entry> </report_data> 

the wanted, correct result produced:

<report_data>    <report_entry>       <id>1</id>       <event>          <start_date>2011-09-06</start_date>          <end_date>2011-09-10</end_date>       </event>    </report_entry>    <report_entry>       <id>1</id>       <event>          <start_date>2011-09-10</start_date>          <end_date>2011-09-15</end_date>       </event>    </report_entry>    <report_entry>       <id>1</id>       <event>          <start_date>2011-09-15</start_date>          <end_date>2011-09-20</end_date>       </event>    </report_entry>    <report_entry>       <id>2</id>       <event>          <start_date>2011-09-20</start_date>          <end_date>2011-09-25</end_date>       </event>    </report_entry>    <report_entry>       <id>2</id>       <event>          <start_date>2011-09-25</start_date>          <end_date>2011-09-30</end_date>       </event>    </report_entry>    <report_entry>       <id>3</id>       <event>          <start_date>2011-09-30</start_date>          <end_date>2011-10-05</end_date>       </event>    </report_entry> </report_data> 

Comments

Popular posts from this blog

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -

javascript - firefox memory leak -

Trying to import CSV file to a SQL Server database using asp.net and c# - can't find what I'm missing -