Search

Hi there, I’m trying to get my head around how to append a string to a node. Very much a beginner at XSLT!

So what I have is a paragraph of text in my xml.

<entry id="7">
            <home-blurb mode="formatted"><p>This is some text in a paragraph that is on the home page.</p></home-blurb>
    </entry>

I’m inside <xsl:template match="home-products/entry"> (ie in the right place!) and what i want to do is append a ‘Read More’ link to the end of this paragraph (there are actually lots of these on the page which all need a read more link). Site is here if you need to see what I mean (under bizbang services) Bizbang

So what I’m trying to do is to use value-of to remove the <p></p>and a variable to store the text for the link with string-join to stick them together with a space in between. But it’s not working no matter what I try so I think I’m doing something horribly wrong!

<xsl:variable name="readmore">
        <a href="{$root}/products/#{product-name/@handle}">Read More</a>
    </xsl:variable>

    <xsl:value-of select="string-join((home-blurb/*, $readmore)' ')"/>

All the xpath is correct etc as is working currently minus the code above.

So some pointers on how to approach this would be much appreciated. Have wondered about trying to use substring-before or substring-after some how. But nothing I try seems to work.

Cheers!

Why not:

<p>
    <xsl:copy-of select="home-blurb/p[1]/node()"/>
    <xsl:text> </xsl:text>
    <a href="{$root}/products/#{product-name/@handle}">Read More</a>
</p>

Ah.. that would be because I didn’t know how to get inside the <p> like that.

That makes WAY more sense though! Thanks.

No problem. A tip: When dealing with HTML, you’ll find yourself using copy-of in conjunction with node() quite a bit, because you can exclude the targeted element itself but still include any elements inside it.

For example, say you’ve got:

<body mode="formatted">This test is a loose cannon. <p>But this paragraph <em>kicks balls</em>!</p></body>

Doing <xsl:copy-of select="body"/> is no good, because you’ll get the <body> element itself in your markup.

Doing <xsl:value-of select="body"/> is no good, because you’ll lose the <p> and the <em> tags.

You’ll often see people do <xsl:copy-of select="body/*"/>, but that’s usually no good either, because you lose that first bit of “loose cannon” text, the one that’s not nested in any other element. So using node() is especially important when you’re doing HTML replacement like pulling the content of a <p> tag and putting it into another element.

Hope that’s helpful :)

I applied both underline and strike-through for text in ODT file..while reading its content.xml, i cant write template in xslt to make both styles to appear in output html..can anyone guide me

Please don’t post the same query in more than one thread.

@czheng just came back to this thread and read your tip above! Very helpful in understanding how to getting use the output of a markdown or html text area!

So am I right in assuming the correct answer or best way to get all the text in your example is just:

<xsl:copy-of select="body/node()"/>

I still can’t really get my head around how/when exactly you use node() in xpath. Had look on W3Schools but it doesn’t really say if you can just drop it in like that if you would need to target each element individually some how?

Sorry if I’m really not getting this….

PS Congrats on the book deal thing - Will definitely be purchasing a copy!

In my example, yes, that’s right.

“Node tests” in XPath are the expressions you normally use to select things. entry/title for example, is a node test. But there are four node tests that look like functions: comment(), node(), processing-instruction(), and text(). You use these in the same way you use XPath expressions normally. For example:

<element id="technoviking">This is the technoviking: <img src="technoviking.jpg"/></element>
  • element/@id selects element’s id attribute node
  • element/text() selects element’s text nodes, in this case: This is the technoviking:
  • element/img selects element’s child img nodes
  • element/node() selects all child nodes (text, elements, etc) inside element

Then there’s name(), which seems akin to text() and node(), but is actually a function. Can often be used similarly though:

  • element/name() would return element

Hope that’s helpful…

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details