Sunday, July 27, 2008

XML Schema 1.1 assertions implementation in Xerces-J

One of the interesting enhancements, that are happening recently to Xerces code base, is XML Schema 1.1 implementation.

The Xerces-J team motivated me to implement some of the XML Schema 1.1 features into Xerces. I've started with the implementation of XML Schema 1.1 facility, "assertions".

I've completed quite a bit of work regarding this, and am hoping that the assertions support I'm writing would be available in Xerces-J in near future.

2008-11-04: Xerces team approved my work so far for assertions implementation, and have committed my patch to the Xerces code base. In the coming weeks, I would be working on integrating XPath 2.0 processing for assertions.

Saturday, July 26, 2008

An elegant XSLT solution

We usually see some nice posts, on the xsl-list.

David Carlisle recently posted a very elegant XSLT solution to a question asked on xsl-list. It's archived here, http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/200807/msg00574.html.

I really liked the following expression, in David's solution:

<xsl:attribute name="level">
<xsl:value-of select="sum(.|preceding::sect[1]/@depth)"/>
</xsl:attribute>

I might have solved this problem differently, but not as elegantly like this. Nice thought, David!

Friday, July 18, 2008

XSLT 2.0 shines over 1.0

I was pondering over XSLT 2.0's advantages over XSLT 1.0, and came up with a simple example that illustrates XSLT 2.0's benefits.

Below are a 1.0 and 2.0 stylesheets, for finding the 1st n fibonacci numbers (and, analysis later on):

XSLT 2.0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:x="http://localhost"
version="2.0">

<xsl:output method="text" />

<xsl:param name="n" />

<xsl:template match="/">
<xsl:for-each select="1 to $n">
<xsl:value-of select="x:fibonacci(position())" /><xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>

<xsl:function name="x:fibonacci" as="xs:integer">
<xsl:param name="n" as="xs:integer" />

<xsl:sequence select="if (($n = 1) or ($n = 2)) then 1 else x:fibonacci($n - 1) + x:fibonacci($n - 2)" />
</xsl:function>

</xsl:stylesheet>

XSLT 1.0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:output method="text" />

<xsl:param name="n" />

<xsl:template match="/">
<xsl:call-template name="iterateAndFib">
<xsl:with-param name="x" select="1" />
</xsl:call-template>
</xsl:template>

<xsl:template name="iterateAndFib">
<xsl:param name="x" />

<xsl:if test="$x <= $n">
<xsl:call-template name="fibonacci">
<xsl:with-param name="n" select="$x" />
</xsl:call-template>
<xsl:text> </xsl:text>
<xsl:call-template name="iterateAndFib">
<xsl:with-param name="x" select="$x + 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>

<xsl:template name="fibonacci">
<xsl:param name="n" />

<xsl:choose>
<xsl:when test="($n = 1) or ($n = 2)">
<xsl:value-of select="1" />
</xsl:when>
<xsl:otherwise>
<xsl:variable name="x">
<xsl:call-template name="fibonacci">
<xsl:with-param name="n" select="$n - 1" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="y">
<xsl:call-template name="fibonacci">
<xsl:with-param name="n" select="$n - 2" />
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$x + $y" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>

Why therefore I think, XSLT 2.0 is better over 1.0,

1. A 2.0 stylesheet can be written with very few lines of code as compared to 1.0 stylesheet. In this case, the 2.0 stylesheet is of 22 lines, and the 1.0 stylesheet is of 51 lines (considering normal indentation markers in code).

2. In a 2.0 stylesheet, there is no need of recursion to iterate. The for-each loop natively supports iteration in a numerical range.

3. In the 2.0 stylesheet, we can utilize the xsl:function construct to write shorter code, which is better logically understood. The recursive calls in xsl:function in this example are easy to understand.

In a 1.0 stylesheet, we need to write named template to achieve recursive calls, which can get cumbersome if logic is complex.

4. In XSLT 2.0, the data model type system has lot more data types, than 1.0 (All built-in XML Schema types, as well user defined types can be used in XSLT 2.0 stylesheets).

I have no doubt, XSLT 2.0 shines over XSLT 1.0.

I read Norman Walsh expressing following thoughts on his blog post, "Every experience that I have with XSLT 2.0 increases my enthusiasm for it.". I totally agree with Norm.

Saturday, July 12, 2008

Constructing StreamSource and StreamResult for JAXP transformation

Recently, I had some tough time converting file paths having spaces into correct StreamSource and StreamResult objects, to be used by the JAXP transformer.

I figured out that below suggestion is probably the best way to solve this issue.

String sourceSystemId = "file:///C:/... .xml"; (use like this, if you are sure that URI string doesn't contain any illegal characters, like spaces etc.)

OR

String sourceSystemId = (new File(pathname)).toURI().toString(); (this will correctly escape characters that are illegal in URIs)

Then, construct StreamSource or StreamResult like following

StreamSource source = new StreamSource(sourceSystemId);

StreamResult result = new StreamResult(outputSystemId);

A useful function exists in XPath 2.0, which applies the %HH escaping convention to a URI, escaping both disallowed characters and reserved characters such as "/" and ":" (encode-for-uri(string $uri-part) → string).

Saturday, June 21, 2008

XML tools for Eclipse

I was searching for some freeware tools for authoring XML and XSD documents. But my bad search inputs didn't return any good results.

So I planned out to create this tooling myself. I decided to use Eclipse as the platform for this, as it is quite robust and very popular.

After few days of effort, I ended up with a very basic prototype. The details are available at, http://gandhimukul.tripod.com/xml/xmleclipse.html. But still lot of work needs to be done on this code base to make it really useful for XML developers, particularly the content assist functionality which is presently missing.

I posted my thoughts about this on xml-dev list.

Dave Carver on xml-dev list suggested to me that there already exists such a tooling. It's the "Web Tools Platform (WTP)" for Eclipse.

I gave WTP a try. Personally speaking, I found it very good. It already has lot's of things that I need in XML GUI tools. Moreover, it's free and open source.

I have now kept WTP in my toolset to author XML, XSD and DTD documents. If required, I might try to tweak it's source code to do something new.

Tuesday, June 10, 2008

self axis vs .

Andrew Welch started a nice discussion about comparison of XPath's self axis vs ., on xsl-list.

Andrew wrote that he has seen people writing self::elem//whatever instead of .//whatever.

I looked at the XPath 2.0 spec to find the relevant definitions. Below are the definitions from the XPath 2.0 spec.

<quote>
the self axis contains just the context node itself

. is known as, "context item expression".
A context item expression evaluates to the context item, which may be either a node (as in the expression fn:doc("bib.xml")/books/book[fn:count(./author)>1]) or an atomic value (as in the expression (1 to 100)[. mod 5 eq 0]).

The context item is the item currently being processed. An item is either an atomic value or a node. When the context item is a node, it can also be referred to as the context node.
</quote>

Wendell Piez wrote,

It also works to test whether the current node is actually an 'elem' when you process it or traverse from it.

Mukul: I personally prefer the style, .//whatever as it is shorter. But I think, there are important use cases for using the self:: axis.

Like for e.g.,

<xsl:template match="*[not(self::elem)]">
<!-- do something -->
</xsl:template>


<xsl:template match="*">
<xsl:if test="not(self::elem)">
<!-- do something -->
</xsl:if>
</xsl:template>


Vyacheslav Sedov wrote,

In XSLT 2.0 I prefer to use "* except elem".

Sunday, May 25, 2008

One-based indexes in XPath

Justin Johansson asked an interesting question on the xsl-list.

Would someone please give me advice as to why "1-based" indexes are used in XPath, such as para[1] instead of para[0] for the first para item/element?

Why does the spec for XPath (and its/XQuery operator/function library) go against the norm for modern programming languages in which zero is the base for array-like collections?

An interesting discussion happened on xsl-list after this query.

Colin Adams wrote: Zero is not the norm for modern programming languages. It might well be for ancient ones. It is a very poor choice, justifiable only when trying to squeeze the last ounce of speed in a highly numerically-intensive application.

And even there it is not justified - you simply use data structures that have an unused first element, and so avoid the subtract one operation in that way.

I reasoned:
Let's say, we have to select a node as following:

following-sibling::xx[1]

To me traversal on following (or say preceding) axis will make sense if indexes start from 1.

I also think 0 based indexes in low level languages (I consider Java or C to be low level than XPath. I am talking about assembly languages too.) have relation to hardware addressing.

For e.g., a memory might have addresses ranging from 0000 to 1111 (this is just a small amount of memory). This probably has got to do with logic of bits, where 0 has a very important meaning.

Lot of programming languages (also mentioned by you) have 0 based indexes (in arrays, strings etc.), so compilers can easily map them to hardware locations.

Indexes in XPath start from 1 because it's more convenient for the users.

Michael Kay commented on my reasoning as follows, "I don't think hardware addressing is the only benefit of 0-based addressing. It also makes computations easier. If you number the rows and columns on a chessboard from 0-7, and the squares from 0-63, then the square number is row*8+column, whereas with 1-based addressing it is (row-1)*8+column.

And we do sometimes use 0-based logic in real life too. In many countries the "first floor" is the one above where you enter the building; and in many societies a child is "1 year old" between 12 months and 24 months after their birth.

But on balance I do think 1-based logic was the right choice for XPath and XSLT."

Michael further said, "Because the language was designed for users, not for programmers, and users still have this old-fashioned habit of referring to the first chapter in a book as Chapter One. (Though I did once hear Dijkstra refer to the fourth slide in someone's presentation as the third.)

(I fully agree that when handling tables, or subscripting into strings, zero-based addressing would often be much more convenient. There are arguments both ways, and as always, I can't tell you what the actual history of the decision was; I can only post-rationalize it.)".

Owen Rees shared an interesting point: Dijkstra wrote a note "Why numbering should start at zero": http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html.

The book "Informal introduction to ALGOL 68" numbers its chapters from zero. I remember that as being unusual, amusing, and also appropriate given the audience.

Since XSLT does not have multi-dimensional sequences, the issues that arise when multi-dimensional arrays can be treated as one-dimensional arrays do not arise. Zero-based indexing tends to make the index formulae simpler when accessing a multi-dimensional array with a one-dimensional array access expression but on the whole I think it is best to just not do that sort of thing at all.

I don't think that the age of language or design for programmer or user arguments stand up very well.

FORTRAN is a counterexample to the "old languages use zero" argument, it uses 1. Modern versions of FORTRAN allow the lower bound to be specified (as Algol did) but the default is still 1.

Dartmouth BASIC used zero-based indexing, I have no information about why, but I doubt if it has anything to do with being close to assembly code or concern for the last ounce of speed.

I think that both of these languages were originally aimed at people who did not think of themselves as being or intending to become programmers.

One related point here is that those thinking in terms of other programming languages may be misled by the syntactic similarity of the XPath expression para[1] to an array indexing expression in various other languages. Understanding that para[1] is just a shorthand for para[position()=1] moves the issue to the question of why position() is defined the way it is.

Defining last() to be the context size means that context position has to count from one unless you are going to cause either 'last' or 'size' to have a very counterintuitive meaning.