Complications A Stylesheet That Generates a Stylesheet That Emulates a for Loop

page 76 This approach works, but were doing an awful lot of work to create some fairly simple elements. For all the XSLT elements were generating with xsl:element elements, we have to declare the namespace for each one. The obvious way of handling this would be to generate a namespace declaration on the xsl:stylesheet element: xsl:attribute name=xmlns:xsl http:www.w3.org1999XSLTransform xsl:attribute Unfortunately, the XSLT specification states in section 7.1.3 that this isnt legal. What we did in our previous example was add the namespace attribute to all XSLT elements we need to generate. The XSLT processor is not required to use the namespace prefix we specified in the xsl:element , by the way. To help us get around this awkward problem, the XSLT specification provides the xsl:namespace-alias element. This provision allows us to define an alias for the XSLT namespace or any other namespace we want to use; well use the normal XSLT namespace for the stylesheet elements we use, and well use the alias for the stylesheet elements we generating. Heres how our new stylesheet looks: ?xml version=1.0? xsl:stylesheet version=1.0 xmlns:xsl=http:www.w3.org1999XSLTransform xmlns:xslout=can be anything, doesnt matter xsl:output method=xml indent=yes xsl:namespace-alias stylesheet-prefix=xslout result-prefix=xsl xsl:template match=||text|comment|processing-instruction xsl:copy xsl:apply-templates select=||text|comment|processing-instruction xsl:copy xsl:template xsl:template match=for-loop xslout:call-template name=for-loop xslout:with-param name=i select={index-variable} xslout:with-param name=increment select={increment} xslout:with-param name=operator xsl:attribute name=select xsl:textxsl:text xsl:value-of select=operator xsl:textxsl:text xsl:attribute xslout:with-param xslout:with-param name=testValue select={test-value} xslout:call-template xsl:template xsl:template match=for-loop mode=generate-template xslout:variable name=newline xslout:text xslout:text xslout:variable xslout:template name=for-loop xslout:param name=i select=index-variable xslout:param name=increment select=increment xslout:param name=operator select=operator xslout:param name=testValue select=test-value xslout:param name=iteration select=1 xslout:variable name=testPassed xslout:choose xslout:when test=starts-withoperator, = xslout:if test=i = testValue xslout:texttruexslout:text page 77 xslout:if xslout:when xslout:when test=starts-withoperator, = xslout:if test=i = testValue xslout:texttruexslout:text xslout:if xslout:when xslout:when test=starts-withoperator, = xslout:if test=i = testValue xslout:texttruexslout:text xslout:if xslout:when xslout:when test=starts-withoperator, = xslout:if test=i = testValue xslout:texttruexslout:text xslout:if xslout:when xslout:when test=starts-withoperator, xslout:if test=i testValue xslout:texttruexslout:text xslout:if xslout:when xslout:when test=starts-withoperator, xslout:if test=i testValue xslout:texttruexslout:text xslout:if xslout:when xslout:otherwise xslout:message terminate=yes xslout:textSorry, the for-loop emulator only xslout:text xslout:texthandles six operators xslout:text xslout:value-of select=newline xslout:text | | = | = | = | =. xslout:text xslout:textThe value xslout:text xslout:value-of select=operator xslout:text is not allowed.xslout:text xslout:value-of select=newline xslout:message xslout:otherwise xslout:choose xslout:variable xslout:if test=testPassed=true xslout:commentFrom your stylesheet:xslout:comment xsl:apply-templates select= xslout:commentEnd of text from your stylesheetxslout:comment xslout:call-template name=for-loop xslout:with-param name=i select=i + increment xslout:with-param name=increment select=increment xslout:with-param name=operator select=operator xslout:with-param name=testValue select=testValue xslout:with-param name=iteration select=iteration + 1 xslout:call-template xslout:if xslout:template xsl:template xsl:template match= xslout:stylesheet version=1.0 xsl:apply-templates select=for-loop mode=generate-template xslout:template match= xsl:apply-templates select= xslout:template xslout:stylesheet xsl:template xsl:stylesheet page 78 Throughout our stylesheet, we used the usual xsl namespace for the stylesheet elements we use, and the xslout namespace for the stylesheet elements we generate. Notice that though we define the xslout namespace on the xsl:namespace-alias element, we still have to declare it on the xsl:stylesheet element. Also note that the value we define for the xslout namespace doesnt matter; the value referred to by the xsl:namespace-alias is used instead. Here is the stylesheet generated by our stylesheet-generating stylesheet: ?xml version=1.0 encoding=UTF-8? xslout:stylesheet xmlns:xslout=http:www.w3.org1999XSLTransform version=1.0 xslout:variable name=newline xslout:text xslout:variable xslout:template name=for-loop xslout:param select=index-variable name=i xslout:param select=increment name=increment xslout:param select=operator name=operator xslout:param select=test-value name=testValue xslout:param select=1 name=iteration xslout:variable name=testPassed xslout:choose xslout:when test=starts-withoperator, = xslout:if test=i = testValue xslout:texttruexslout:text xslout:if xslout:when xslout:when test=starts-withoperator, = xslout:if test=i = testValue xslout:texttruexslout:text xslout:if xslout:when xslout:when test=starts-withoperator, = xslout:if test=i = testValue xslout:texttruexslout:text xslout:if xslout:when xslout:when test=starts-withoperator, = xslout:if test=i = testValue xslout:texttruexslout:text xslout:if xslout:when xslout:when test=starts-withoperator, xslout:if test=i testValue xslout:texttruexslout:text xslout:if xslout:when xslout:when test=starts-withoperator, xslout:if test=i testValue xslout:texttruexslout:text xslout:if xslout:when xslout:otherwise xslout:message terminate=yes xslout:textSorry, the for-loop emulator only xslout:text xslout:texthandles six operators xslout:text xslout:value-of select=newline xslout:text | | = | = | = | =. xslout:text xslout:textThe value xslout:text xslout:value-of select=operator xslout:text is not allowed.xslout:text xslout:value-of select=newline xslout:message xslout:otherwise xslout:choose xslout:variable xslout:if test=testPassed=true xslout:commentFrom your stylesheet:xslout:comment page 79 tr xmlns:xsl=http:www.w3.org1999XSLTransform td align=center xsl:value-of select=iteration td td align=center xsl:value-of select=i td tr xslout:commentEnd of text from your stylesheetxslout:comment xslout:call-template name=for-loop xslout:with-param select=i + increment name=i xslout:with-param select=increment name=increment xslout:with-param select=operator name=operator xslout:with-param select=testValue name=testValue xslout:with-param select=iteration + 1 name=iteration xslout:call-template xslout:if xslout:template xslout:template match= html xmlns:xsl=http:www.w3.org1999XSLTransform head titleText generated by our for loop processortitle head body h1Text generated by our for loop processorh1 table border=1 tr thIteration th thValue of iii th tr xslout:call-template name=for-loop xslout:with-param select=0 name=i xslout:with-param select=1 name=increment xslout:with-param name=operator select== xslout:with-param select=10 name=testValue xslout:call-template table body html xslout:template xslout:stylesheet When we execute the generated stylesheet, it produces the following HTML document. When rendered in a browser, the document generated by the stylesheet generated by our other stylesheet looks like Figure 4-1 . html head META http-equiv=Content-Type content=texthtml; charset=UTF-8 titleText generated by our for loop processortitle head body h1Text generated by our for loop processorh1 table border=1 tr thIteration ththValue of iiith tr tr td align=center1tdtd align=center0td tr tr td align=center2tdtd align=center1td tr tr td align=center3tdtd align=center2td tr page 80 tr td align=center4tdtd align=center3td tr tr td align=center5tdtd align=center4td tr tr td align=center6tdtd align=center5td tr tr td align=center7tdtd align=center6td tr tr td align=center8tdtd align=center7td tr tr td align=center9tdtd align=center8td tr tr td align=center10tdtd align=center9td tr tr td align=center11tdtd align=center10td tr table body html Figure 4-1. HTML document generated by our generated stylesheet Notice in the generated document that the HTML title and h1 values come directly from the XML template, as do the table headings and the definition of the HTML table itself. page 81

4.9 Summary

Weve covered a lot of ground in this chapter, havent we? Weve gone over all of the basic elements you need to add logic and branching to your stylesheets. We discussed some of the similarities between XSLT and other programming languages you might know; more importantly, we discussed how XSLT is different from most of the code youve probably written. In particular, the use of recursion and the principles of variables that dont change take some getting used to. Despite the learning curve, most of the common tasks youll need to do will be similar to the exercises weve gone through in this chapter. Now that weve covered these basic elements, well talk about links and references, discovering ways to build links between different parts of an XML document. page 82

Chapter 5. Creating Links and Cross-References

If youre creating a web site, publishing a book, or creating an XML transaction, chances are many pieces of information will refer to other things. This chapter discusses a several ways to link XML elements. It reviews three techniques: • Using the id function • Doing more advanced linking with the key function • Generating links in unstructured documents

5.1 Generating Links with the id Function

Our first attempt at linking will be with the XPath id function.

5.1.1 The ID, IDREF, and IDREFs Datatypes

Three of the basic datatypes supported by XML Document Type Definitions DTDs are ID , IDREF , and IDREFS . Heres a simple DTD that illustrates these datatypes: --glossary.dtd-- --The containing tag for the entire glossary-- ELEMENT glossary glentry+ --A glossary entry-- ELEMENT glentry term,defn+ --The word being defined-- ELEMENT term PCDATA --The id is used for cross-referencing, and the xreftext is the text used by cross-references.-- ATTLIST term id ID REQUIRED xreftext CDATA IMPLIED --The definition of the term-- ELEMENT defn PCDATA | xref | seealso --A cross-reference to another term-- ELEMENT xref EMPTY --refid is the ID of the referenced term-- ATTLIST xref refid IDREF REQUIRED --seealso refers to one or more other definitions-- ELEMENT seealso EMPTY ATTLIST seealso refids IDREFS REQUIRED In this DTD, each term element is required to have an id attribute, and each xref element must have an refid attribute. The ID and IDREF datatypes work according to two rules: • Each value of the id attribute must be unique. • Each value of the refid attribute must match a value of an id attribute elsewhere in the document.