Reputation: 79
I have an XML file that contains some escaped XHTML, something like this:
<AuthorBio>
<p>Paragraph with<br/>forced line break.</p>
</AuthorBio>
I'm trying to transform it with XSLT into the following:
<ParagraphStyleRange>
<CharacterStyleRange>
<Content>
Paragraph with
forced line break.
</Content>
</CharacterStyleRange>
<Br/>
</ParagraphStyleRange>
Here's a simplified version of my XSLT:
<xsl:template match="AuthorBio">
<xsl:for-each select="p">
<ParagraphStyleRange>
<xsl:apply-templates select="./node()"/>
<Br/>
</ParagraphStyleRange>
</xsl:for-each>
</xsl:template>
<xsl:template match="AuthorBio/p/text()">
<CharacterStyleRange>
<Content><xsl:value-of select="."/></Content>
</CharacterStyleRange>
</xsl:template>
<xsl:template match="br">


</xsl:template>
Unfortunately, this is giving me the following result:
<ParagraphStyleRange>
<CharacterStyleRange>
<Content>
Paragraph with
</Content>
</CharacterStyleRange>


<CharacterStyleRange>
<Content>
forced line break.
</Content>
</CharacterStyleRange>
<Br/>
</ParagraphStyleRange>
I realize that is because my template is matching p/text()
, and therefore breaks at <br/>
. But—unless I'm approaching this entirely the wrong way—I can't think of a way to select the entire contents of an element, including all child nodes. Something like copy-of
, I suppose, except removing the wrapping element. Is this possible? Is there a way to match the entire contents of a node, but not the node itself? Or is there a better way to go about this?
Upvotes: 1
Views: 657
Reputation: 70598
It looks like you only you want to output the CharacterStyleRange
and Content
elements once for each paragraph. If so, change the template that currently matches AuthorBio/p/text()
to match just p
instead, and output the ParagraphStyleRange
, CharacterStyleRange
and Content
altogether in there.
Try this XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="AuthorBio">
<xsl:apply-templates select="p" />
</xsl:template>
<xsl:template match="p">
<ParagraphStyleRange>
<CharacterStyleRange>
<Content>
<xsl:apply-templates />
</Content>
</CharacterStyleRange>
<Br/>
</ParagraphStyleRange>
</xsl:template>
<xsl:template match="br">
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1