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
Post a Comment