List all namespaces in Firefox with XSLT - firefox

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.

Related

how to find the preceding sibling of a link

I have the following I am trying to analyse using xpath
<table>
<tr>
<td>Name</td>
<td>Info</td>
<td>Download</td>
</tr>
<tr>
<td>Name2</td>
<td>Info</td>
<td>Download</td>
</tr>
....
<tr>
..
</tr>
</table>
I have the following xpath to grab the download links
$xpath->query("//a[text()='Download']/#href");
What I am trying to figure out is the query to send to grab the Name of each of the downloads.
The page has no div id markups at all, just plain table, tr, td tags.
I have tried something like
$xpath->query("//preceding-sibling::a[text()='Download']");
Does anyone have any idea on this?
Close!
Given a particular context node (here, the href attribute for a download), you want to find the eldest sibling of the td containing the context node. So your relative path should first ascend to the td and then find the oldest sibling:
parent::a/parent::td/preceding-sibling::td[last()]
or more briefly (and without assuming that there are no elements like p or span intervening between the td and the a):
ancestor::td[1]/preceding-sibling::td[last()]
Some users find the reverse numbering of nodes on the preceding-sibling axis confusing, so it may feel simpler to say that what you really want is the first td child of the smallest containing tr:
ancestor::tr[1]/child::td[1]
If you need in a single pass to pick up all the download links and the textual label for them, then how you do it depends on the context in which you're using XPath. In XSLT, for example, you might write:
<xsl:apply-templates select="//a[text()='Download']/#href"/>
and then fetch the label in the appropriate template:
<xsl:template match="a/#href">
<xsl:value-of select="string(ancestor::tr[1]/td[1])"/>
:
<xsl:value-of select="."/>
</xsl:template>
In other host languages, you will want to do something similar. The key problem is that you have to iterate over the nodes matching your expression for href, and then for each of those nodes you need to move back in the document to pick up the label. How you say "evaluate this second XPath expression based on the current node from the first XPath expression" will vary with your environment.

how to display an image using xslt

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.

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 :-) ]

XPath selection while excluding elements having certain attribute values

My first post here - it's a great site and I will certainly do my best to give back as much as I can.
I have seen different manifestations of this following question; however my attempts to resolve don't appear to work.
Consider this simple tree:
<root>
<div>
<p>hello</p>
<p>hello2</p>
<p><span class="bad">hello3</span></p>
</div>
</root>
I would like to come up with an XPath expression that will select all child nodes of "div", except for elements that have their "class" attribute equal to "bad".
Here is what I have tried:
/root/div/node()[not (#class='bad')]
... However this doesn't seem to work.
What am I missing here?
Cheers,
Isaac
When testing your XPath here with the provided XML document, the XPath seems to be indeed selecting all child nodes that do not have an attribute class="bad" - these are all the <p> elements in the document.
You will note that the only child node that has such an attribute is the <span>, which indeed does not get selected.
Are you expecting the p node surrounding your span not to be selected?
I have been working with XPath in a Java program I'm writing. If you want to select the nodes that don't have class="bad" (i.e. the <span> nodes, but not the surrounding <p> nodes), you could use:
/root/div/descendant::*[not (#class='bad')]
Otherwise, if you want to select the nodes that don't have a child with class='bad', you can use something like the following:
/root/div/p/*[not (#class='bad')]/..
the .. part selects the immediate parent node.
The identity transform just matches and copies everything:
<xsl:template match="#*|node()" >
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
But you add a null transform that more specifically matches the pattern you want to exclude:
<xsl:template match="span[#class='bad']" />
( you can also add a priority attrib if you want to be more explicit about which one has precedence. )
Welcome to SO, Isaac!
I'd try this:
/root/div/*[./*[#class != "bad"]]
this ought to select all child elements (*) of the div element that do not have a descendant element with a class attribute that equals bad.
Edit:
As per #Alejandros comment:
/root/div/*[not(*/#class "bad")]

Resources