how to display an image using xslt - image

I have the following code
<xsl:template name="toggle">
<xsl:param name="target"/>
<xsl:param name="show"/>
<input type="image" src="glass.png" />
<xsl:attribute name="onclick">
toggle('<xsl:value-of select="$target"/>','<xsl:value-of select="$show"/>');
</xsl:attribute>
</input>
</xsl:template>
I want to add an external image which is not part of xml file. I want to replace my Submit button with an image.
When using the above code I am unable to get the image as output.
Any ideas on how to do it?

Do you know what HTML you want to generate?
If you do, then tell us.
If you don't, then you have an HTML problem, not an XSLT problem.
Never try to write code in XSLT until you know what output HTML you want it to produce. Actually, I think it was Dijkstra who said you should never start writing any program until you know what output you want it to produce. A good principle. When applied to XSLT, remember that the output in this sense is an HTML document, not a screen displayed by the browser.

Related

List all namespaces in Firefox with XSLT

In XSLT, I try to list all namespaces in the document. Here is the code:
<xsl:for-each select="namespace::*">
<xsl:value-of select="name()"/>:
<xsl:value-of select="."/><br/>
</xsl:for-each>
If I run it in Chrome or Safari, it works well. But Firefox shows no results: "namespace::" is empty.
Does anybody know if there is an alternative selector for all namespaces in a document?
This seems to have been an open bug for 18 years:
https://bugzilla.mozilla.org/show_bug.cgi?id=94270
You can find all the namespaces that are actually used using namespace-uri() on every element and attribute, but I don't think there's any other way of finding namespaces that aren't used.
Of course (I declare a personal interest here) you could switch horses and use Saxon-JS.

Getting nodes under a specific node element

I need help with my problem over here or at least some advice. I am parsing a HTML document using a HTMLcleaner with the use of XPATH.
I have something like this:
<html>
[code and other <h4> tags]
<h4>Random name</h4>
Text I want to get
Text I want to get 2
Text I want to get 3
Text I want to get 4
<h4> Random name 2 </h4>
Text I don't want to get
[code and other <h4> tags]
</html>
Ok. I have several <h4> tags, each one of them with <a> tags and with the some text. My problem is that I don't know how to get all the respective the text from a specific , just like a "h4[i]". I tried something like this but it didn't work:
String xpath = "h4["+number+"]//a" //where number will increment
Thank you in advice for you help!
Use:
/*/h4[1]/following-sibling::a[not(preceding-sibling::h4[2])]/text()
XSLT - based verification:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select=
"/*/h4[1]/following-sibling::a[not(preceding-sibling::h4[2])]/text()"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the following XML document (the provided fragment, wrapped in a single top element to become an well-formed XML document):
<html>
<h4>Random name</h4>
Text I want to get
Text I want to get 2
Text I want to get 3
Text I want to get 4
<h4> Random name 2 </h4>
Text I don't want to get
</html>
The Xpath expression is evaluated and all selected (text) nodes are copied to the output:
Text I want to get Text I want to get 2 Text I want to get 3 Text I want to get 4

why does this xpath selector fail?

given the following html
<p>
<div class="allpricing">
<p class="priceadorn">
<FONT CLASS="adornmentsText">NOW: </FONT>
<font CLASS="adornmentsText">$1.00</font>
</p>
</div>
</p>
why does
//div[#class="allpricing"]/p[#class="priceadorn"][last()]/font[#class="adornmentsText"][last()]
return the expected value of $1.00
but adding the p element
//p/div[#class="allpricing"]/p[#class="priceadorn"][last()]/font[#class="adornmentsText"][last()]
returns nothing?
You cannot place a div inside a p. The div start closes the p automatically. See
Nesting block level elements inside the <p> tag... right or wrong?
I've often found that fixing the cases was the culprit. XPath 1.0 is case sensitive and unless you take care of the mixed cases explicitly, it will fail in a lot of cases.
XPath is case-sensitive.
None of the provided XPath expressions selects any node, because in the provided XML document there is no font element with an attribute named class (the element font has a CLASS attribute and this is different from having a class attribute due to the different capitalization).
Due to the same reason, font and FONT are elements with different names.
These two XPath expressions, when evaluated against the provided XML document, produce the same wanted result:
//div[#class="allpricing"]
/p[#class="priceadorn"]
[last()]
/font[#CLASS="adornmentsText"]
[last()]
and
//p/div[#class="allpricing"]
/p[#class="priceadorn"]
[last()]
/font[#CLASS="adornmentsText"]
[last()]
XSLT - based verification:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
'//div[#class="allpricing"]
/p[#class="priceadorn"]
[last()]
/font[#CLASS="adornmentsText"]
[last()]'/>
=============
<xsl:copy-of select=
'//p/div[#class="allpricing"]
/p[#class="priceadorn"]
[last()]
/font[#CLASS="adornmentsText"]
[last()]
'/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<p>
<div class="allpricing">
<p class="priceadorn">
<FONT CLASS="adornmentsText">NOW: </FONT>
<font CLASS="adornmentsText">$1.00</font>
</p>
</div>
</p>
the two expressions are evaluated and the results of this evaluation are copied to the output:
<font CLASS="adornmentsText">$1.00</font>
=============
<font CLASS="adornmentsText">$1.00</font>
You describe your source as an HTML rather than an XML document, but you haven't explained how you parsed it. If you parse it using an HTML parser, the parser will "repair" it to turn it into valid HTML, which means that the tree it constructs doesn't directly reflect what you wrote in the source. XPath sees this "repaired" tree, not the original.

Umbraco not executing code before displaying it

I am doing a Umbraco site (my first) and I am having a serious issue with loading an image on one of my pages.
I created a new template and one section of the code I inserted the following:
<a href="{umbraco.library:NiceUrl($currentPage/../#id)}">"
<xsl:value-of select="$currentPage/../#nodeName" />
</a>
When I look at the results in the browser it displays the results exactly the same, it does not get executed before rendering. ie I see this when I look at the "view source" in the browser:
<a href="{umbraco.library:NiceUrl($currentPage/../#id)}">
<xsl:value-of select="$currentPage/../#nodeName" />
</a>
The confusing part is that when I run the following :
<img src='<umbraco:Item field="articlePhoto" runat="server"></umbraco:Item>' />
It actually generates this tag :
<img src="~/media/554/bath.png">
The main thing I am trying to do is load a dynamic field/url into an image tag.
Any help would be greatly appreciated.
Thanks
I'm assuming you actually have two problems here and that they're not linked.
First Problem: Code not executing
You are trying to execute XSLT code directly inside the template. The template only accepts what you would normally find in a ASPX page (e.g. HTML, Server Controls, Registered Umbraco Controls etc) and will not parse any XSLT constructs but output them directly into the source, as exemplified in your question.
You will need to create an XSLT file in the developer section, along with it's associated macro, which is usually created automatically along with the XSLT. Then you simply import the macro into the template.
Template Snippet:
<umbraco:Macro Alias="MyMacro" runat="server" />
XSLT Snippet:
<a href="{umbraco.library:NiceUrl($currentPage/../#id)}">
<xsl:value-of select="$currentPage/../#nodeName" />
</a>
Second Problem: Image not showing
It's weird Umbraco is preprending the ~ symbol as your code is indeed correct (it's working on my Umbraco - Version 4.7.1). As a work-around, try creating an XSLT file and using the following XSLT code. At least with XSLT you're able to put in coding logic, which will be needed as your pages become more complex.
XSLT Snippet:
<xsl:if test="$currentPage/articlePhoto != ''">
<img src="{$currentPage/articlePhoto}" />
</xsl:if>
Hope that helps.

local-name() support in Collective.xdv

I have a Plone 3.5 site and I am trying to embedded Simple Social's FB Like action for a content in a collective.xdv theme. The FB Like function is embedded in an XML tag
<fb:like></fb:like>
I am trying to select its XPATH via
//*[local-name()="like"]
However, I do not see any output. Is the above supported in collective.xdv? Is there another way to select the fb:like tag in XPATH?
The libxml2 HTMLParser used by lxml and thus xdv/diazo strips namespace prefixes, so you should be able to select it with "//like".
You will need to add some xslt code to fix up those tags, as they must be rendered as in order to work:
<xsl:template match="activity|add-profile-tab|bookmark|comments|friendpile|like|like-box|live-stream|login-button|pronoun|recommendations|serverFbml|profile-pic|user-status">
<xsl:element name="fb:{local-name()}" xmlns:fb="http://www.facebook.com/2008/fbml">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
While xdv/diazo could be made to work with the XMLParser you would then need to ensure that you added an xmlns:fb="..." declaration to your document and that all your input was valid xhtml, which is difficult to ensure with browser based html editors.
Laurence
aiui, that's not how local-name works. You need to match on a namespace-qualified tag, and then local-name() returns the unqualified name. I believe //* is only returning a nodeset of tags in the default namespace.
Have you tried //fb:like? [I know, that's far too easy - and I think it's wrong - but then again, it is easy :-) ]

Resources