While developing an XSLT-based solution today, I've stumbled across an almost unbelievable fact: you can only test whether two strings are equal or unequal in XSL stylesheets (for example, in xsl:if or xsl:when conditions), not whether one is larger or smaller than the other (in the usual alphabet-based sense). The greater-than and less-than operators only work on numbers.
Before anyone rushes forward and tells me that XPATH 2.0 has compare function that does exactly what I need, let me remind you that XPATH 2.0 is only implemented in a handful of standalone XSLT translators and is (at least as of October 2007) completely useless when you need browser-based transformation.
And just in case someone starts explaining about the collating sequences, let me conclude this post by saying that you can sort on strings with the xsl:sort instruction in XPATH 1.0, but cannot compare them. I'm really wondering what the standard designers were thinking …
XML Handling in Microsoft SQL Server 2005
InformIT.com has just published my article describing how you can use XML data type in SQL Server 2005 to optimize SQL queries and updates.
XSLT-generated documents are never rendered in quirks mode in Firefox
I'm a heavy user of browser-side XSLT transformations (you can learn more about the techniques I'm using in the article I wrote for InformIT.com). While I'm usually generating HTML 4.0 (or event XHTML-) compliant transformation results, every now and then I would like to put the browser in quirks mode, for example, when I would like the text of my page to span the whole browser window (which is easily done with a TABLE with height set to 100% in quirks mode).
While this trick works nicely in Internet Explorer, Firefox produces standards mode layout (with TABLE contents condensed at the top of the screen) regardless of the HTML output the XSLT transformation generates. Probably this is due to the fact that the XSLT transformation in Firefox does not produce interim HTML string, but transforms DOM tree into another DOM tree.
While this trick works nicely in Internet Explorer, Firefox produces standards mode layout (with TABLE contents condensed at the top of the screen) regardless of the HTML output the XSLT transformation generates. Probably this is due to the fact that the XSLT transformation in Firefox does not produce interim HTML string, but transforms DOM tree into another DOM tree.
Create your own animated …loading… indicator
I've needed a copyright-free animated GIF that I could use as a rotating wheel in my “Loading, please wait” overlay DIV. Asking Google about loading animation returned www.ajaxload.info as the first hit. It turned out to be an excellent web site that builds you an animated GIF with foreground and background colors you specify out of more than a dozen templates. Highly recommended ;)
Use xsl:key to link nodes in input XML document
In a previous post, I've described how you can use local variables and XPath expressions to link elements in the input XML document. An even better (and probably faster) alternative is to use the XSL keys. For example, you might want to link the target element with the source element in an XML document based on the ref attribute of the source and the id/@num attribute of the target:
<data>You can define a key that will select the target element or another one that will select the text child of the target element (in which case you have to be a bit more creative in the use part of xsl:key definition):
<source id="abc" ref="123" />
<target>
<text>Message</text>
<id num="123" />
</target>
</data>
<xsl:key name="target" match="target" use="id/@num" />Assuming you want to display the text child of the target node, you could use either key in your transformation. If you use the target key, it returns the target node, so you have to continue with the XPath expression to get its text child; using the ttext key gives you the text node immediately:
<xsl:key name="ttext" match="target/text" use="../id/@num" />
<xsl:template match="source">
<xsl:variable name="target" select="@target" />
Source <xsl:value-of select="@id" />
target <xsl:value-of select="key('target',@target)/text" />
ttext <xsl:value-of select="key('ttext',@target)" />
</xsl:template>
Floating misteries
I guess all would be well if we would just take enough time and read through the CSS standards (at least through the sections documenting the box model and layouts). As that will probably never happen, floats remain a black magic to a lot of people (myself included sometimes). The Make Your Site BulletProof With Floats article published by Peachpit.com could make things a bit clearer … or at least you'll find a few good working examples.
Mouse event bubbling might produce unexpected results
The unexpected consequences of the mouse event bubbling are best illustrated with an example. Consider the following HTML markup (and note that in real life you should not declare event handlers in HTML markup):
Probably the best workaround is to compare the event target (browser-dependent, use xEvent to get browser-independent code) with the current element.
<div onmouseover="d_a()" onmouseout="d_b()">When the mouse is moved from outside the DIV to the first line, d_a and p_a are called as expected. When the mouse moves from Line 1 to Line 2, p_b (expected), as well as p_a (highly unexpected) are called even though the mouse has not left the DIV. p_a is called due to event bubbling; the mouseover event bubbles from its target through all the target's ancestors toward the document object.
<p onmouseover="p_a()" onmouseout="p_b()">Line 1</p>
<p>Line 2</p>
</div>
Probably the best workaround is to compare the event target (browser-dependent, use xEvent to get browser-independent code) with the current element.
On-demand load of JavaScript libraries
With a creative approach to DOM model, you can load JavaScript libraries on demand from your web pages. What you need to do is to create a SCRIPT element, set its SRC attribute and insert it into the document. You could use a function similar to this one ...
function LoadScript(url)
{
var lib = document.createElement(’script’);
lib.type=’text/javascript’;
lib.src= url;
document.getElementsByTagName(’head’)[0].appendChild(s);
}
... or you could use a safer xLoadScript function from the X library.
The X library also provides a xSmartLoadScript function to stop you from loading the same library multiple times.
In a recent post on PeachPit.com, Kris Hadlock gives you a few ideas where this functionality might come handy.Link multiple elements from source XML data
An interesting question was asked in the Sun's Java forums: “How do I match attributes on different input nodes?” For example, I would like to link the target attribute of the source element in the following XML data with the target node (based on the num attribute of its id child).
<data>While it's easy to select the correct target node, it's harder to get the source attribute into the XPath expression; the only way to do it is to store the source attribute in a local variable and then use the variable value (which is context-independent) in the XPath expression:
<source id="abc" target="123" />
<target>
<text>Message</text>
<id num="123" />
</target>
</data>
<xsl:template match="source">The final XPath expression works as follows:
<xsl:variable name="target" select="@target" />
Source <xsl:value-of select="@id" />
is associated with
<xsl:value-of select="//target[id/@num = $target]/text" />
</xsl:template>
- It selects a target node anywhere in the source XML tree (the // path) such that the num attribute of its id child is equal to the local variable target
- When the target node is selected, the value of the XPath expression is the value of its text child, which is then rendered into a string (collapsing all its descendant text nodes into the final result).
This post is part of You've asked for it series of articles.
How to handle XSLT namespaces
The Teaching XSLT post by Jeni Tennison is focusing mainly on the challenges of teaching XSLT (and I've really enjoyed that angle as I was also a CCSI for a long time), it also contains good recommendations on how to handle the namespaces in XSLT.
Some XSLT best practices
The XPath and XSLT without the pain presentation by Bertrand Delacretaz has some interesting recommendations for XPath and XSLT best practices. Highly recommended.
Match a keyword in space-separated keyword list (attribute value)
A post in Push Button paradise explains how you can use XSLT functions to test whether a keyword is present in space-separated list of keywords (for example, whether an HTML tag has a specific CSS class).
Notes:
- The original problem explanation is somewhat misleading; the @class = 'vcard' test will correctly match if the class attribute is set to vcard, but would not match if vcard is just one of several classes applied to an HTML tag.
- The Microformats wikipedia has code samples solving the same issue in multiple programming languages.
- The best function I've found so far in JavaScript world is the xGetElementsByClassName from the X library.
Storing XML Data in a Relational Database
The Storing XML Data in a Relational Database article just published by InformIT.com describes the various methods you can use to store XML data in an SQL database. I've also tried to explain when it would be appropriate to store XML data in a database and when you'd be better off using the traditional relational database model. The rest of the article details the procedures you can use to insert, query, retrieve and modify the stored XML data.
Interesting: greater-than character does not need to be escaped in XML
I always thought that less-than, ampersand and greater-than character have to be escaped in XML. As Micah Dubinko points out in his blog post, that's not strictly true; greater-than character usually does not have to be escaped (here is the relevant part of the XML standard).
DOM events don't have the “on” prefix
One of the very common mistakes when switching from traditional object-property-based event registration (window.onload = handler) to DOM event registration (window.addEventListener('load',handler)) is the reuse of object property as the event name. The “on” property prefix should not be part of the event name (for example, use load instead of onload and mouseover instead of onmouseover).
To make matters worse, the attachEvent method (Microsoft equivalent of the addEventListener DOM method) expects the event names with the “on” prefix.
To make matters worse, the attachEvent method (Microsoft equivalent of the addEventListener DOM method) expects the event names with the “on” prefix.
Serve SQL data in XML format
InformIT has just published my next article that explains various options you have when your data resides in an SQL database and the client side of your AJAX application expects the data in XML format. The article covers a number of different approaches, including:
- Creating the XML markup in the server-side script
- Using the SQL server to generate the XML markup
- Using server-side XSLT transformation in combination with SQL server-produced XML data
Subscribe to:
Posts (Atom)