tags:

views:

27

answers:

2

I need to append the image element of my XML below the first paragraph of the body element as an HTML img tag using XSLT. Can anybody show me how to do this?

<pages>
    <entry id="18">
        <title handle="design">Design</title>
        <image size="240 KB" path="/uploads" type="image/jpeg">
            <filename>design.jpg</filename>
            <meta creation="2010-08-30T15:23:52+01:00" width="1781" height="1214" />
        </image>
        <body mode="formatted">
            <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sit amet elit vitae arcu interdum ullamcorper. Nullam ultrices, nisi quis scelerisque convallis, augue neque tempor enim, et mattis justo nibh eu elit.</p>
            <p>Quisque ultrices gravida pede. Mauris accumsan vulputate tellus. Phasellus condimentum bibendum dolor. Mauris sed ipsum. Phasellus in diam. Nam sapien ligula, consectetuer id, hendrerit in, cursus sed, leo. Nam tincidunt rhoncus urna. Aliquam id massa ut nibh bibendum imperdiet. Curabitur neque mauris, porta vel, lacinia quis, placerat ultrices, orci.</p>
            <p>Mauris sed ipsum. Phasellus in diam. Nam sapien ligula, consectetuer id, hendrerit in, cursus sed, leo. Nam tincidunt rhoncus urna. Aliquam id massa ut nibh bibendum imperdiet. Curabitur neque mauris, porta vel, lacinia quis, placerat ultrices, orci.</p>
            <p>Nam tincidunt rhoncus urna. Aliquam id massa ut nibh bibendum imperdiet. Curabitur neque mauris, porta vel, lacinia quis, placerat ultrices, orci.</p>
        </body>
    </entry>
</pages>

I want this output.

<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sit amet elit vitae arcu interdum ullamcorper. Nullam ultrices, nisi quis scelerisque convallis, augue neque tempor enim, et mattis justo nibh eu elit.</p>
<p><img src="/uploads/design.jpg" alt="" /></p>
<p>Quisque ultrices gravida pede. Mauris accumsan vulputate tellus. Phasellus condimentum bibendum dolor. Mauris sed ipsum. Phasellus in diam. Nam sapien ligula, consectetuer id, hendrerit in, cursus sed, leo. Nam tincidunt rhoncus urna. Aliquam id massa ut nibh bibendum imperdiet. Curabitur neque mauris, porta vel, lacinia quis, placerat ultrices, orci.</p>
<p>Mauris sed ipsum. Phasellus in diam. Nam sapien ligula, consectetuer id, hendrerit in, cursus sed, leo. Nam tincidunt rhoncus urna. Aliquam id massa ut nibh bibendum imperdiet. Curabitur neque mauris, porta vel, lacinia quis, placerat ultrices, orci.</p>
<p>Nam tincidunt rhoncus urna. Aliquam id massa ut nibh bibendum imperdiet. Curabitur neque mauris, porta vel, lacinia quis, placerat ultrices, orci.</p>

Current XSLT

<xsl:for-each select="services/entry[title/@handle=$service]">
    <h1><xsl:value-of select="title" /></h1>
    <xsl:copy-of select="body/*" />
    <xsl:if test="image != ''">
        <ing src="{$workspace}{image/@path}/{image/filename}" width="200" class="top pull-1 left" />
    </xsl:if>
</xsl:for-each>
A: 

This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <xsl:template match="text()"/>
    <xsl:template match="title">
        <h1>
            <xsl:value-of select="."/>
        </h1>
    </xsl:template>
    <xsl:template match="node()[ancestor::body]|@*[ancestor::body]" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="body/p[1]">
        <xsl:call-template name="identity"/>
        <p>
            <img src="{../../image/@path}/{../../image/filename}" alt="" />
        </p>
    </xsl:template>
</xsl:stylesheet>

Output:

<h1>Design</h1>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sit amet elit vitae arcu interdum ullamcorper. Nullam ultrices, nisi quis scelerisque convallis, augue neque tempor enim, et mattis justo nibh eu elit.</p>
<p>
    <img src="/uploads/design.jpg" alt="" />
</p>
<p>Quisque ultrices gravida pede. Mauris accumsan vulputate tellus. Phasellus condimentum bibendum dolor. Mauris sed ipsum. Phasellus in diam. Nam sapien ligula, consectetuer id, hendrerit in, cursus sed, leo. Nam tincidunt rhoncus urna. Aliquam id massa ut nibh bibendum imperdiet. Curabitur neque mauris, porta vel, lacinia quis, placerat ultrices, orci.</p>
<p>Mauris sed ipsum. Phasellus in diam. Nam sapien ligula, consectetuer id, hendrerit in, cursus sed, leo. Nam tincidunt rhoncus urna. Aliquam id massa ut nibh bibendum imperdiet. Curabitur neque mauris, porta vel, lacinia quis, placerat ultrices, orci.</p>
<p>Nam tincidunt rhoncus urna. Aliquam id massa ut nibh bibendum imperdiet. Curabitur neque mauris, porta vel, lacinia quis, placerat ultrices, orci.</p>
Alejandro
Cheers Alejandro, that worked a treat.
Eoghan O'Brien
@Eoghan O'Brien: I'm glad it has helped you!
Alejandro
A: 

XSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
<xsl:template match="title"/>
<xsl:template match="filename"/>
<xsl:template match="body/p">
    <p>
        <xsl:apply-templates/>
    </p>
    <xsl:if test="not(preceding-sibling::p)">
        <p>
            <img src="{../../image/@path}/{../../image/filename}" alt="" />
        </p>
    </xsl:if>
</xsl:template>
</xsl:stylesheet>

Output:

<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam sit amet elit vitae 
arcu interdum ullamcorper. Nullam ultrices, nisi quis scelerisque convallis, augue neque tempor enim, et mattis justo nibh eu elit.</p>
<p><img src="/uploads/design.jpg" alt="" /></p>
<p>Quisque ultrices gravida pede. Mauris accumsan vulputate tellus. Phasellus condimentum bibendum dolor. Mauris sed ipsum. Phasellus in diam. Nam sapien ligula, consectetuer id, hendrerit in, cursus sed, leo. Nam tincidunt rhoncus urna. Aliquam id massa ut nibh bibendum imperdiet. Curabitur neque mauris, porta vel, lacinia quis, placerat ultrices, orci.</p>
<p>Mauris sed ipsum. Phasellus in diam. Nam sapien ligula, consectetuer id, hendrerit in, cursus sed, leo. Nam tincidunt rhoncus urna. Aliquam id massa ut nibh bibendum imperdiet. Curabitur neque mauris, porta vel, lacinia quis, placerat ultrices, orci.</p>
<p>Nam tincidunt rhoncus urna. Aliquam id massa ut nibh bibendum imperdiet. Curabitur neque mauris, porta vel, lacinia quis, placerat ultrices, orci.</p>
joe
@joe: When you post some output in answer, it is assumed that you have tested. But your stylesheet fragment could not ever output that, because `apply-templates select="*"` doesn't apply to text nodes...
Alejandro
@joe: remove `xsl:copy` or literal `p`, otherwise you end up with nested `p`. `<xsl:apply-templates/>` will work just fine if you don't overwrite built-in rule for text nodes. If you apply templates to attributes, you're goint to need some rule for those, otherwise built-in rule will output their values. A minor, your test could be just `not(preceding-sibling::p)`
Alejandro
Thanks for the help Alejandro. My answer is correct now. I like you approach better though because it is more robust and maintainable.
joe