XSLT By Doug Tidwell The unconfirmed error reports are from readers. They have not yet been approved or disproved by the author or editor and represent solely the opinion of the reader. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification This page was updated June 17, 2008. UNCONFIRMED errors and comments from readers: [2.5.2] Listing "org.apache.fop.apps.CommandLine greeting.fo greeting.pdf"; On MacOSX 10.5 I get the following error: $java org.apache.fop.apps.CommandLine greeting.fo greeting.pdf Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/fop/apps/CommandLine My Java version: $java -version java version "1.5.0_13" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_13-b05-237) Java HotSpot(TM) Client VM (build 1.5.0_13-119, mixed mode, sharing) I'm not sure why this fails. Up to this point all the examples worked on MacOSX. (1-999) Executable statements that cross line boundaries lack continuation characters; This occurs throughout the book. For example, the following command: java org.apache.xalan.9780596000530.Process -in greeting.xml -xsl fo-greeting.xsl -out greeting.fo which appears in section 2.5.2, if copied and pasted to a terminal window, will be executed as two lines, producing unexpected results. Such commands should be formatted with a continuation character (backslash) at the end of each continued line. E.g., java org.apache.xalan.9780596000530.Process -in greeting.xml -xsl fo-greeting.xsl \ -out greeting.fo I recommend also mentioning this continuation character convention in the preface under "Conventions Used in This Book". (1) straight down the Figure 1-1; Page http://www.oreilly.com/catalog/9780596000530/chapter/ch05.html:

Glossary Listing: -

should be closed with

, not . {10} First bullet point; The day attribute isn't defined to be between 1 and 31. It's only defined to be an integer not greater than 31, so for example day="-2" will validate. Similarly with month & year. (18) First para; The DOMit servlet no longer works. http://www.ibm.com/developerworks/features/xmlvalidatorform.html When clicking on "Create the DOM tree button", gives "The page you requested cannot be displayed." (19) 2nd paragraph; Typo: "For more details on how to install and configure the XML tools to work with the brower" "brower" should be "browser" {24} second bullet, third sentence reads: For example, is ... should read: For example, is ... or: For example, is ... reason: In the HTML/XHTML DTD it is illegal to have a

tag as contents of an

tag. The

element can be a child of the element or a element, but not the

element. (25) Step 5, last text paragraph; Ik the last text paragraph on page 25 of XSLT, i found the following sentence (between brackets): 'If more than one element matches....' This sentence is slightly misplaced, i believe. In the given example the 'greeting' element is the root node of the xml document. But, as the document node can only have one child, as documented earlier in the book. I think placing the bracketed sentence here would confuse readers. Giving the readers a warning that in this example there can't be more than one 'greeting' element is better. (28) 2nd example; I believe that the last "z" in this text: should be an "x": (28) last para and its line of code; "This template does nothing." Why tell me this? Does it just consume the comment() and processing- instruction() items? Why not say so? (28) First paragraph and its block of code; This is one example of several I could raise with respect to chapter 2. I have written HTML, XHTML, and manuals for years. I came to the book with some familiarity with XML, both as a means of data representation and as a mechanism for producing documents. What good does it do to tell me "this template processes the root and any of its children" and then show me a match string of "*|/" without giving me a clue what *|/ DOES/REPRESENTS? {31}, the bottom example has but I think it needs to be: unless he is referring to an earlier example. It's a bit unclear as is. {32-33} In the `Hello World SVG File' stylesheet (and resulting SVG file); I tried this example, and used the Apache XML Project's batik 1.1rc4 to view the resulting SVG file. I couldn't see a colo(u)r gradient. I mailed the batik-users mailing list to see if batik implemented colo(u)r gradients. Thierry Kormann replied: > Batik does gradients. > > The gradient you have defined is in 'objectBoundingBox' (the default value is > of the 'gradientUnits' attribute). It means that all the attributes on the > radialGradient element is relative to the bounding box of the painted element > (your text element in that case - so between 0 and 1 or 0% and 100%). > > To fix your example, add gradientUnits='userSpaceOnUse' on the radialGradient. > And may be, send a bug report to the author :) > > Thierry. I made this alteration, and all is well. (33) code block in middle of page; I read this closely enough to note that the sequence of attributes in the radialGradient element was changed. Even if you ARE going to keep giving us multi-line examples in which only a handful of characters are actually the point of the example, but without somehow pointing them out (italics, bold, numbered callout, ...) why not SAY that the sequence of the attributes was reversed because (perhaps?) it was processed on a last-in-first-out basis -- and that of course the sequence does not matter? [35] last line (command line execution of FOP; At least with the current version of FOP (0.20.1), there is no such class org.apache.fop.apps.CommandLine The main command-line class is now org.apache.fop.apps.Fop (34) XML insert fo-greeting.xsl; It would seem that FOP project has made some changes that mean version 0.20.4 of FOP requires subtle changes to the sytle sheet as presented in the book, and as in the download, or the next stage, the creation of the PDF file, will fail. I'm far from certain that this is a perfect fix, but: Change: To: and Change: To: The Stylesheet is then: {45} 5th paragraph; The text states, "...we could have declared that a Shakespearean sonnet is the default type..." In the accompanying code, "Shakespearean" *is* the default value (not really a type). Also the text states, "If the type is defined as #IMPLIED, both of the elements we just mentioned will have an attribute node with a name of type and a value of Shakespearean." If the default value is #IMPLIED, the example without an attribute does not include a 'type' attribute. Is my confusion real, or am I reading this incorrectly? [45] 2nd paragraph; The following sentence is not correct: "..., and the name() of the is auth:last-name (any element contained in the element is from the auth namespace unless specifically declared otherwise)." The "Namespaces in XML" specification states: "If the URI reference in a default namespace declaration is empty, then unprefixed elements in the scope of the declaration are not considered to be in any namespace. ... The default namespace can be set to the empty string. This has the same effect, within the scope of the declaration, of there being no default namespace." As the has no prefix and there is no default namespace declaration the is not in any namespace. According to the XPath specification the expanded-name of is the pair of {last-name, null}. The name() returns a QName representing an expanded-name so in the case of the {last-name, null} expanded-name the name() should return the "last-name" string. (49) 1st paragraph; is: should be: (51) 3rd paragraph; is: /sonnet/writers::* should be: /sonnet/writers:* {50} 4th para; I think that where it says 'Thus, the XPath expression /sonnet/auth:author/text() returns the following text' the experssion should be /sonnet/auth:author//text() or /sonnet/auth:author/*/text() in order to return that text. text() just seems to return the concatenated text nodes of that node and not of children unless you ask for them. {51} First list item of section "Using Wildcards"; It says, "The asterisk (*), which selects all element nodes in the current context. Be aware that the asterisk wildcard selects element nodes only; attributes, text nodes, comments, or processing instructions aren't included." This is not true. It really should say that * matches any nodes of "the principal node type." In the examples given, that type happens to be "element." However, given the document:

some junk

the location path: //attribute::* which contains an asterisk node test, matches attr1="this" attr2="that" I think the book is basically saying that //* matches the test and p elements, but it neglects to say that is because //* is just abbreviated syntax for /descendant-or-self::node()/child::* and in that context an asterisk matches only element nodes. It would probably be clearer to start with the unabbreviated syntax first and then to explain the abbreviated syntax in terms of that. I realize that this is a pretty technical detail, but given that many programmers treat O'Reilly books as the "official" software manuals (and with good reason), attention to detail matters. [53] Under "parent axis" heading; Book states "The expressions parent::sonnet and ../sonnet are equivalent." This is not true. parent::sonnet selects the node's parent, if it's a sonnet. ../sonnet selects siblings of the context node which are sonnets. From the XPath spec: "a location step of .. is short for parent::node(). For example, ../title is short for parent::node()/child::title and so will select the title children of the parent of the context node." (71) Last paragraph; "As the XSLT processor cycles through all the and elements ..." should read "... all the
and elements ..." (73) 3rd from last line; calcuateArea should be calculateArea (73) Paragraph below 'Parameters' heading; "You can pass templates with..." should be "You can pass parameters with..." {74-75} p.74 - template, pp.74-75 - template; In both cases the opening and closing element names should be preceded with the "xsl" prefix. {77} Xalan; My version of xalan (1.0.1) needs single quotes around the parameter values as well, just like Oracle's. (Quick check of http://xml.apache.org tells me that newer versions do not require them though) {83} pseudocode example; The line of pseudocode that reads lastOfString = replaceString( ... ) should read lastOfString = replaceSubstring( ... ) {86} code immediately below 'Implementation' heading; For the xsl:param tag with name attribute "operator", the value for the 'select' attribute should read: select="'='" Otherwise, when running the example (for-loop.xsl) against an XML file with a single empty element, Xalan gives this error: ---begin error--- (Location of error unknown)XSLT Error (javax.xml.transform.TransformerConfigurationException): javax.xml.transform.TransformerException: java.lang.RuntimeException: Programmer's assertion in getNextStepPos: unknown stepType: -1 ---end error--- My environment: RedHat 7.1 Sun JDK 1.3.1_01 Xalan2 Java 2.2.D11 Note the same problem exists with the "operator" parameter for other examples on page 86 and page 87. {86} 1st paragraph (bulleted), second sentence; The second sentence which outlines the options for the operator variable says that not equal is "<> (coded as <>)". However, the following stylesheet listing (starting on page 87) uses "!=" for not equals. (87) bottom source sample; When using the sample "Chapter4\for-loop.xsl" I got a parse error from my 9780596000530 engine (msxml v4 sp1). The error was due to an error in the piece of code on page 87: the third line should be (or at least, that did the trick for me): {104} 2nd code example; in 2nd code example on the page: .. .... @id is defined as an attribute of the child node "term" in the DTD preceeding, yet this Xpath refers to attribute of "glentry". one fix would be: .. ..... {120} 2nd paragraph from bottom; I think normalizeSpace() should read normalize-space(). (Also in the index.) {137} The last xsl fragment at the bottom of the page; The code now reads: It should read: In other words, the xpath specification should have only the first "/". [141] Code under section "A Brute-Force Approach"; The intermediate stylesheet sorts the address elements by last-name and first-name. The idea of the example however, is to sort the address elements by zip. It appears therefore, that the zip order and address order may still be out of step. The answer would be for the intermediate stylesheet to sort the address elements by zip (and then optionally also last-name and first-name). (146) complete stylesheet; The complete stylesheet on page 146 does not correspond to the example file, Chapter6/namegrouper3.xsl. {150} Code example, line 14; / missing from end of element (150) entire page; The stylesheet on pages 150-152 omits the ending slash in _most_ empty tags. For example: , should read: (154) paragraph under heading "Generating output to initialize a variable"; This paragraph refers to the variable runningTotal when it should, I think, refer to the variable orderTotal. (197) 2nd paragraph; The files Compare_es.java and Compare_es.class are missing from the examples files. (202) 4th paragraph; 2nd and 3rd sentences should be changed as follows: Original: --------- If this particular element has a required="true" attribute, the XML data contains . The value of this element is an empty string, the font is changed to bold and red. Corrected: ---------- If this particular element has a required="true" attribute, and the XML data contains , and the value of this element is an empty string, then the font is changed to bold and red. {examples} Chapter5/crossref4.xsl; The example does not use the 'targetLanguage' variable. The problem also shows itself in the generated HTML - dictionary4.html. {examples} Chapter5/crossref3.xsl; line 60 should be: Presently the line uses "name" rather than "href". [243] Under 'Optional Attributes' in the paragraph describing 'select'; This concerns the default behavior of the 'select' attribute. The last sentence reads, "Without this attribute, all element children of the current node are selected." The default is all child nodes, not just child elements. For example, a correct sentence would be, "Without this attribute, all child nodes of the current node are selected." The W3C specification reads, "In the absence of a select attribute, the xsl:apply-templates instruction processes all of the children of the current node, including text nodes." (http://www.w3.org/TR/ 9780596000530#section-Applying-Template-Rules) (298) example; I've been trying to use the info you give in your book "XSLT" (on pages 298 and 307) regarding and and each separately seems to work. I can either generate a DOCTYPE in my xml output or I can generate a stylesheet reference in my output. HOWEVER, when I try and do both, the DOCTYPE generated contains "root-not-available" rather than the actual desired value of "svg". Again, the "svg" comes out nicely if I dont also try to generate the stylesheet reference (via xsl:processing-instruction). So, how do *you* generate an xml document with a specified DOCTYPE and that also references an external css stylesheet? Here is an example of the "bad" output I get.... How do I generate this in XSLT just the same except that "root-not-available" says "svg" ??? here is my XSLT... (try separately commenting out the xsl:output and/or xsl:processing-instruction tags) href="gannt.css" type="text/css" {337} "Boolean Operators" Tidwell says that the operator "!=" "tests whether two expressions are not equal." This, it appears, is not strictly correct; or at least it should be made clear that "A != B" is not equivalent to "not(A = B) [338] 2nd paragraph; String comparisons Original : "For less-than and greater-than comparisons, the character codes are compared." This is incorrect. Both strings are converted to numbers (with the "number()" function) and then compared. Note : This correct rule is stated in the 4th paragraph on the same page. Implication : You can't compare strings characterwise unless you use a sorted, temporary node-set. Example : "A" >= "A" is actually false, as is "B" >= "A" as these are converted to NaN >= NaN, with is false by IEEE 754 [394] Bottom, flowing onto top of 395; I'd like to confirm the report for 394 in "Unconfirmed" -- the output is the result of running the stylesheet on itself (not on the XML example offered prior to the stylesheet listing). {394} last paragraph; I don't belive the output for the example for the name() function is correct. The example gives us an XML file and a XSL stylesheet but I don't think the output is from running the stylesheet on the XML file. I think the output that's printed is the output of running the stylesheet on the STYLESHEET. This is very confusing for someone trying to learn how to write and use stylesheets. [440] Bottom of the page; The description of output-escaping on page 440-1 is backwards. When 'disable-output- escaping="yes", the actual character will be written, not the escape value. The description of output-escaping on pages 319 and 321, which accompanies the and elements, is correct. The following is from the latest spec at www.w3.org: 16.4 Disabling Output Escaping Normally, the xml output method escapes & and < (and possibly other characters) when outputting text nodes. This ensures that the output is well-formed XML. However, it is sometimes convenient to be able to produce output that is almost, but not quite well-formed XML; for example, the output may include ill-formed sections which are intended to be transformed into well-formed XML by a subsequent non-XML aware process. For this reason, XSLT provides a mechanism for disabling output escaping. An xsl:value-of or xsl:text element may have a disable-output-escaping attribute; the allowed values are yes or no; the default is no; if the value is yes, then a text node generated by instantiating the xsl:value-of or xsl:text element should be output without any escaping. For example, < should generate the single character <. [440] last sentence in first question's answer; The statement "This element is replaced with..." should really be "This element generates..." This wording matches the wording of the answer to the next question on the same page, and also, the misleading use of the phrase "is replaced by" probably resulted from the over-use of cutting and pasting by the preparer of the text since this example is similar to the "replace-substring" example earlier in the book.