Reputation: 179
My output is actually looking fine, but the xslt-prozessor does it 238 (exactly) times. Like he does 238 iterations, I get 238 copys of the same... The original XML-file has 1000 row-elements, the output XML-file has 238000 post-elemnts. What am I missing?
My XML
<csv_data><row>
<stuff1>Stuff_here_1</stuff1>
<stuff2>Stuff_here_2</stuff2>
<stuff3>Stuff_here_3</stuff3>
<stuff4>Stuff_here_4</stuff4>
<stuff5>Here will be some text</stuff5>
</row>
<row>
<stuff1>Stuff_here_11</stuff1>
<stuff2>Stuff_here_22</stuff2>
<stuff3>Stuff_here_33</stuff3>
<stuff5>Here will be some text</stuff5>
</row></csv_data>
My XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:template match="csv_data">
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<someHeader>
<text>
<body>
<div type="sometype">
<xsl:apply-templates select="@* | node()"/>
</div>
</body>
</text>
</TEI>
</xsl:template>
<xsl:template match="//row">
<xsl:for-each select="//row">
<post attribute1="{stuff1}" attribute2="{stuff2}" attribute3="{stuff3}" attribute4="{stuff4}">
<p>
<xsl:value-of select="stuff5"/>
</p>
</post>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Views: 29
Reputation: 338316
You are missing the fact that <xsl:apply-templates>
already works like a loop. You don't need the <xsl:for-each>
at all.
Write your <xsl:template match="row">
so that it produces the correct output for one <row>
. The template will be executed multiple times automatically.
I recommend to a more specific <xsl:apply-templates>
call, though. You only want to select <row>
elements, so the logical thing would be to use select="row"
.
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
>
<xsl:template match="csv_data">
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<someHeader>
<text>
<body>
<div type="sometype">
<xsl:apply-templates select="row" />
</div>
</body>
</text>
</TEI>
</xsl:template>
<xsl:template match="row">
<post attribute1="{stuff1}" attribute2="{stuff2}"
attribute3="{stuff3}" attribute4="{stuff4}" />
</xsl:template>
</xsl:stylesheet>
Another thing to note is that you don't need to (and should not) write absolute XPaths in <xsl:template match="...">
expressions. Only part of the expression needs to match, so using match="//row"
is unnecessary and match="row"
is perfectly fine.
Upvotes: 2
Reputation: 67311
I think you can change //row
to .
In these lines you define a template for any <row>
<xsl:template match="//row">
<xsl:for-each select="//row">
The for-each
will again(!) perform the action for any <row>
Try it like this
<xsl:template match="row">
<xsl:for-each select=".">
The for-each
will run with the data below the <row>
Upvotes: 1