Reputation:
My XML looks like this:
<element>
<AttrValue someatt="a">
<StyledElement>
<Container />
<StyledElement>
<Paragraph />
<StyledElement>
<PlainText someValue="some Text" />
</StyledElement>
</StyledElement>
<StyledElement>
<Paragraph />
<StyledElement>
<PlainText TextValue="another Text" />
</StyledElement>
</StyledElement>
</StyledElement>
</AttrValue>
</element>
The output should look like this:
<element>
<AttrValue someatt="a"> some Text , another Text (text from child nodes - seperated by comma) </AttrValue>
</element>
I have a multiple elements like this so maybe it should be with for-each?
Upvotes: 0
Views: 531
Reputation: 338108
<xsl:for-each>
is not necessary for this. I recommend separate templates as the more readable alternative:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:template match="element">
<xsl:copy>
<xsl:apply-templates select="AttrValue" />
</xsl:copy>
</xsl:template>
<xsl:template match="AttrValue">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates select=".//PlainText/@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="PlainText/@*">
<xsl:value-of select="." />
<xsl:if test="position() < last()">, </xsl:if>
</xsl:template>
</xsl:stylesheet>
Output with your source XML:
<element>
<AttrValue someatt="a">some Text, another Text</AttrValue>
</element>
Upvotes: 1
Reputation: 106796
I have assumed that the TextValue
attribute of you second <PlainText>
element is misstyped and actually is a someValue
attribute.
Here is some XSLT that should do the job:
<xsl:template match="/element">
<element>
<xsl:for-each select="AttrValue">
<AttrValue someatt="{@someatt}">
<xsl:for-each select="//PlainText">
<xsl:if test="position() != 0">, </xsl:if>
<xsl:value-of select="@someValue"/>
</xsl:for-each>
</AttrValue>
</xsl:for-each>
</element>
</xsl:template>
This is basically a nested <xsl:for-each>
loop. The only "trick" is how position()
is used to place commas between text values.
Upvotes: 0