CSS by itself is insufficient for presentation for all but the most well structured of documents. HTML works well with CSS because HTML has a structural ordering that works well with the CSS model (as to be expected, given that CSS evolved in response to HTML). Some years ago I wrote a couple of chapters for a book on XML and CSS, showing how you can apply CSS to XML, but as I proved back even then, very, very few XML schemas are in fact even remotely appropriate for direct presentation with CSS.
What about XSLT? Here things get a little more interesting. You can bind an XSLT to an XML document to perform client-side rendering. The most obvious mechanism is through the use of the ?xml-stylesheet PI. Unfortunately once past this AJAX-based transformations become somewhat trickier, because while there may be support for an XSLT transformation API within a browser, such support is far from uniform.
Personally, I'd like to see an inline <transform> tag in HTML5:
<transform
stylesheet="xs:anyURI"
data=""xs:anyURI"
type="mime-type"
refresh="timeInterval"
media="xs:NMTokens"
asynch="xs:boolean"
atserver="xs:boolean"
method="xs:NMToken"
form="xs:IDRef"
id="
xs:ID">
Default Internal Content
</transform>
This would be a display tag that would load the data either from a server or from a block of XML in the client, then would apply they associated stylesheet to that data in order to provide output that would replace the current child content. The mime-type would be the transformation language - application/xslt+xml, text/javascript, application/xquery+xml. The @refresh attribute would the time in seconds between refresh times, with a default of 0 (no refresh). If @stylesheet is not included, then this acts as an inline xinclude statement. Initially, before any content is loaded, the Default Internal Content will be displayed. The media statement would contain an indication about what context the transformation would be invoked, with NMTokens including "web","print","mobile","tv","braille" and so forth.
The @atserver attribute is a hint back to the server that it should attempt the transformation server side rather than client side. Normally, if a client side operation fails, then an error is raised. In this case, if @atserver is true, then the client would send post the data to the server script, which would then perform the transform and return the contents (as shown below).
In terms of APIs, they'd be about what you would expect:
Transform:refresh() will perform an automatic refresh of the transformation and reset the refresh interval,
Transform:clear() will clear the transformation and restore the default internal content.
Transform:childNodes() will return the nodes resulting from the transformation.
Transform:stylesheet() will return the current stylesheet document (not the URL) as a node
Transform:data() will return the current data() used prior to transformation.
Transform:asynch is a boolean property indicating whether the resource is called synchronously or asynchronously (the default).
It would also have four events:
Transform::ontransform - invoked prior to the transformation being called. This provides a way to hook a javascript function to the transform, passing the appropriate object in the $evt variable.
Transform::ontransformcomplete - invoked after a successful call to the transformation.
Transform::ontransformerror - invoked when a transformation fails. The result is an $error object containing the the relevant message data.
Transform::ondataloaderror - invoked when data fails to load or parse.
To change the working data or the transformation, simply change the appropriate attributes.
The benefit to this is simple - it provides a way to invoke multiple stylesheets in a platform independent manner. It makes simple AJAX calls a no brainer. It places no explicit requirement upon vendors to support a given transformation language - if a language isn't supported, then an error is thrown and the default content continues to be displayed. It provides a simple way for a print system to generate the full rendering of a page without having to get a full snapshot of the more complicated aspects of the DOM, and with the media attribute it means that you can display certain transforms in specific contexts. For instance, the following set of transforms:
<transform data=""myNewsFeed.atom.xml"" stylesheet="atom-display-web.xsl" type="application/xslt+xml" media="web" refresh="10s">Loading News Feed</transform>
<transform data=""myNewsFeed.atom.xml"" stylesheet="atom-display-mobile.xsl" type="application/xslt+xml" media="mobile" refresh="10s">Loading News Feed</transform>
would generate a news display from an atom feed, but while the first would be tailored for web display, the second would display for mobile devices exclusively. If your source was in json and your transformation was in an inline script, then the transform would look something like:
<script type="javascript">
function showNews($evt){
var $data = "$evt.data();
var $buf = [];
foreach($item in $data){$buf.push("<li><b><a href="'"+$item.link+"'>"+$item.title+"</a></b><div" class='desc'>"+$item.body+"</div></li>");};
var $content = "<ul>"+$buf.join("")+"</ul>";
return $content;
}
window.>
var $news = document.getElementById("news");
$news.addEventListener("ontransform","showNews");
}
</script>
<transform data=""myNewsFeed.js"" type="application/javascript" refresh="10s" id="news"/>
Or you could just put the invocation directly on the element:
<transform data=""myNewsFeed.js"" type="application/javascript" refresh="10s" id="news" ontransform="showNews(this)">Loading News Feed</transform>
If the script was external, you could even go one step farther and say:
<transform data=""myNewsFeed.js"" stylesheet="newsFeedScripts.js" type="application/javascript" refresh="10s" id="news" ontransform="showNews(this)">Loading News Feed</transform>
One final case - @atserver. If this attribute is set to true then rather than evaluating the data on the client, it would post the data to the script given in stylesheet, and use the result from that to populate the transform element. The @form attribute is the id of a form that contains the relevant data, although @method and @stylesheet will override form @method and @action in the form if provided.
The simple case:
<transform data=""myNewsFeed.xml"" stylesheet="newsFeedTransform.xq" atserver="true" method="GET">Loading News Feed</transform>
calls the XQuery script on the server and passes it the myNewsFeed.xml, using the HTTP 1.1/GET prototocol (this is an idempotent invocation). The results will then be output as the new children of the <transform> element.
The more complex case:
<form id="search_constraints" method="GET">
<div><b>Search: <input name="q" value="" id="q"/></b></div>
</form>
<transform data=""myNewsFeed.xml"" stylesheet="newFeedTransform.xq" atserver="true" form="search_constraints">Loading News Feed</transform>
will use the search_contraints form to send both the XML data content and the "q" query string parameter to newFeedTransform.xq on the server using an HTTP/GET invocation. Note that in neither case is it necessary to specify the language @type, as that's now within the province of the server to determine.
The point on all of this is that such an addition to HTML5 would be a boon to both JSON and XML, because it moves a lot of the framework scripting out of the normal flow of the HTML. It also satisfies the shift towards client-side tech while still working within the mandate that David notes - the server becomes less responsible for presentation, though it still may be necessary to transform the content server side into a simplified format (for instance, converting data from a query against a prescriptions database into a genericode or JSON representation that could then be consumed more readily by an XSLT or Javascript converter. The client is still responsible for presentation, but the server has to help by making the data more readily consumable.
================================
As an addendum to the original post: one of the central criticisms that Ian Hixon has about XML is that for the average developer it is too complex and scary, a point that I'm not totally sure I disagree with, after having seen Java developers at one organization I worked with actually get hives when contemplating having to work with XML without the familiar Java layers between them and the raw code. A solution like the above provides a way to "hide" the XML from the developer while still making it possible to make use of XML (and XSLT and/or XQuery) if the developer has need for it. It can degrade gracefully. It works well with the existing HTML paradigm, up to and including subclassing forms as appropriate.
Realistically, it may turn out that the best way of working with HTML at this point is to make use of precisely this kind of system - hiding the complexity of these services behind easy to use tags. It would certainly make stylesheets much more useful, since it gets you away from the all or nothing requirements imposed by global stylesheets (which essentially have to recreate (or at a minimum copy) the entire HTML document in their transformations). It also treats javascript as a valid styling mechanism in a manner that's consistent with how the language itself works.
Something to think about, anyway.
Kurt Cagle
XML Architect
Lockheed / US National Archives ERA Project
On Sun, Dec 5, 2010 at 9:08 AM, Costello, Roger L.
<costello@mitre.org> wrote:
Hi Folks,
Consider this:
The <a> element is, without a doubt, the most
important element in HTML. It turns our text
into hypertext. It is the connective tissue
of the World Wide Web. [1]
Recap: hyperlinking functionality is important on the Web.
The XML hyperlinking functionality, as specified by XLink and XPointer, is dead. [2]
Can XML truly be a Web technology without hyperlinking functionality?
/Roger
[1] "HTML5 for Web Designers" by Jeremy Keith, p. 20.
[2] XPointer is dead. What about XLink? http://www.stylusstudio.com/xmldev/200908/post90310.html
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]