Shed Simas
Shed Simas

Reputation: 79

How do I match all of an element's content with a XSLT?

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&#x2028;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">
 &#x2028;
</xsl:template>

Unfortunately, this is giving me the following result:

<ParagraphStyleRange>
 <CharacterStyleRange>
  <Content>
   Paragraph with
  </Content>
 </CharacterStyleRange>
 &#x2028;
 <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

Answers (1)

Tim C
Tim C

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>&#x2028;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 1

Related Questions