XSLT 2.0 File Splitting

B

bbembi_de

Hello everyone,

I know how to split a xml input file in multiple output files with the
xsl:result-document command.

But I have still one problem.
My input file looks like this (simplified):

<root>
<student>
<name>peter</name>
<course>1</course>
</student>
<student>
<name>sarah</name>
<course>2</course>
</student>
</root>


now I want to create a file for every course. but the input file isn't
sorted by course.
I don't know how many course files there will be and the output files
names should be the course names.

My problem is that the xslt processor tells me that there is already a
file named <course> if the parser gets to the second student with the
same course.

What can I do?

thanks.

bye bembi
 
P

Pavel Lepin

I know how to split a xml input file in multiple output
files with the xsl:result-document command.

<root>
<student>
<name>peter</name>
<course>1</course>
</student>
<student>
<name>sarah</name>
<course>2</course>
</student>
</root>


now I want to create a file for every course. but the
input file isn't sorted by course.
I don't know how many course files there will be and the
output files names should be the course names.

My problem is that the xslt processor tells me that there
is already a file named <course> if the parser gets to the
second student with the same course.

This is a simple grouping problem. There might be a more
XSLT2-idiomatic solution, but using good ole XSLT1 grouping
tricks for your sample document:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="course-name" match="course" use="."/>
<xsl:key name="courses" match="course"
use="count(.|key('course-name',.)[1])"/>
<xsl:key name="student-course" match="student"
use="course"/>
<xsl:template match="/">
<xsl:apply-templates select="key('courses',1)"/>
</xsl:template>
<xsl:template match="course">
<xsl:result-document href="{.}.xml">
<result course="{.}">
<xsl:apply-templates
select="key('student-course',.)"/>
</result>
</xsl:result-document>
</xsl:template>
<xsl:template match="student">
<xsl:copy>
<xsl:copy-of select="name"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
 
M

Martin Honnen

Pavel said:
This is a simple grouping problem. There might be a more
XSLT2-idiomatic solution,

Here is a sample using XSLT 2.0 xsl:for-each-group and the functions
current-group and current-grouping-key:

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

<xsl:eek:utput method="xml" indent="yes"/>

<xsl:template match="/">
<xsl:for-each-group select="root/student" group-by="course">
<xsl:result-document href="course{current-grouping-key()}.xml">
<course name="{current-grouping-key()}">
<xsl:apply-templates select="current-group()"/>
</course>
</xsl:result-document>
</xsl:for-each-group>
</xsl:template>

<xsl:template match="student">
<xsl:copy>
<xsl:copy-of select="name"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top