$theTitle=wp_title(" - ", false); if($theTitle != "") { ?> } else { ?> } ?>
by Andrew Johnstone
In: General
6 Jul 2006After toying with some XPath’s and a fair amount of XSL lately (& getting lost in XPath), I feel it would be wise to place something here to look back on…
Marcus Tucker, introduced me to Stylus Studio of which I am very thankful as XmlSpy didn’t help me to deduce the problem with one of the XPaths, (infact ‘Select Previous Link’)
So heres some snippets.
Select Previous Link – Select First Preceding Node @id with with specified PathID
//project/article[@id=$PathID]/preceding-sibling::article[1]/@id
Select Next Link – Select Following Sibling @id with with specified PathID
//project/article[@id=$PathID]/following-sibling::article/@id
Also using the following are very handy for helping you know where abouts you are:
<xsl:copy-of select=”parent::*”>
<xsl:copy-of select=”position()”>
<xsl:template match="*" mode="namespace">
<xsl:for-each select="namespace::*">
<xsl:if test="not(../ancestor::*[namespace::*[name() = name(current()) and . = current()]][last()])">
<xsl:value-of select="name(..)" /> defines <xsl:text />
<xsl:choose>
<xsl:when test="name()">xmlns:<xsl:value-of select="name()" /></xsl:when>
<xsl:otherwise>xmlns</xsl:otherwise>
</xsl:choose>
<xsl:text />="<xsl:value-of select="." />"<xsl:text />
</xsl:if>
</xsl:for-each>
</xsl:template>
<!-- generate namespace declarations as needed for current
element node and its attributes.
-->
<xsl:template name="findNamespace">
<xsl:variable name="curnode" select="." />
<xsl:for-each select=".|@*">
<xsl:variable name="vName" select="substring-before(name(), ':')"/>
<xsl:variable name="vUri" select="namespace-uri(.)"/>
<xsl:variable name="vAncestNamespace">
<xsl:call-template name="findAncNamespace">
<xsl:with-param name="pName" select="$vName"/>
<xsl:with-param name="pUri" select="$vUri"/>
<xsl:with-param name="pNode" select="$curnode" />
</xsl:call-template>
</xsl:variable>
<xsl:if test="not(number($vAncestNamespace))">
<!-- not sure if "parent::*" should be "$curnode/parent::*" -->
<xsl:if test="parent::* or namespace-uri() or contains(name(), ':')">
<xsl:text> </xsl:text>
<span>
<xsl:value-of select="'xmlns'"/>
<xsl:if test="contains(name(), ':')">
<xsl:value-of select="concat (':', $vName)"/>
</xsl:if>
</span>
<span>="</span>
<span>
<xsl:value-of select="namespace-uri()"/>
</span>
<span>"</span>
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:template>
<!-- Return 1 if an ancestor of pNode (or an attribute thereof)
has the same prefix (pName) and namespace-uri (pUri) as
the current node, and there is no closer ancestor (or attribute
thereof) that has the same prefix but a different namespace-uri. Return 0 otherwise. -->
<xsl:template name="findAncNamespace">
<xsl:param name="pNode" select="."/>
<xsl:param name="pName" select="substring-before(name(), ':')"/>
<xsl:param name="pUri" select="namespace-uri(.)"/>
<xsl:choose>
<xsl:when test="not($pNode/parent::*)">0</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="($pNode/.. | $pNode/../@*)
[$pName = substring-before(name(), ':') and
$pUri = namespace-uri()]">
1
</xsl:when>
<xsl:when test="($pNode/.. | $pNode/../@*)
[$pName = substring-before(name), ':')]">
<!-- and $pUri !=namespace-uri() -->
0
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="findAncNamespace">
<xsl:with-param name="pNode" select="$pNode/.."/>
<xsl:with-param name="pName" select="$pName"/>
<xsl:with-param name="pUri" select="$pUri"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
I also wrote up some XSL to retreive parameters from XSL being parsed on the client, now I haven’t tested this although it may be beneficial to someone trying to extract parameters on the client-side.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:eg="http://schemas.example.com/"
>
<xsl:output
omit-xml-declaration="yes"
method = "html"
indent = "no"
encoding = "UTF-8"
/>
<msxsl:script language="JScript" implements-prefix="eg">
function GetParam(name) {
var start=location.search.indexOf("?"+name+"=");
if (start<0) start=location.search.indexOf("&"+name+"=");
if (start<0) return '';
start += name.length+2;
var end=location.search.indexOf("&",start)-1;
if (end<0) end=location.search.length;
var result=location.search.substring(start,end);
var result='';
for(var i=start;i<=end;i++) {
var c=location.search.charAt(i);
result=result+(c=='+'?' ':c);
}
return unescape(result);
}
</msxsl:script>
<xsl:template match="/">
<xsl:value-of select="eg:GetParam('Query')" />
</xsl:template>
<xsl:stylesheet>
I have been a developer for roughly 10 years and have worked with an extensive range of technologies. Whilst working for relatively small companies, I have worked with all aspects of the development life cycle, which has given me a broad and in-depth experience.
1 Response to Handy XSL Fragments & XPath’s
david steare
June 13th, 2011 at 1:35 pm
I think liquid xml editor would also meet your needs,
://www.liquid-technologies.com/XML-Editor.aspx