XML in a Nutshell By Elliotte Rusty Harold and W. Scott Means This errata page lists errors outstanding in the most recent printing. If you have technical questions or error reports, you can send them to booktech@oreilly.com. (Please specify the printing date of your copy.) This page was last modified on December 13, 2001. 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 Confirmed errors: (xiv): After "Constant width bold" add "is used for:" (xiv): In the fifth bullet point, delete "should be deleted" [35] list in middle of page ? Permits zero or one of the element * Permits zero or one of the element + Permits zero or one of the element should read more like: ? Permits zero or one of the element * Permits zero or more of the element + Permits one or more of the element (37) In the last code fragment on the page, should be changed to That is, delete the last parenthesis in that line. {122} In Example 7-8 "%MODULE-qname.mod;" should be "%cafe-qname-1.mod;". (143) In the last paragraph, change "in the specified node" (with an n) to "in the specified mode" (with an m) <158> In the 5th paragraph, 3rd line "equivalent to the unabbreviated form" should read "equivalent to the abbreviated form". (181) In the second to last paragraph change "nonfiction" to "manual". [183] 3 last paragraphs: Replace "XPointers can identify multiple..." to the end of the page and two code fragments with this: If you're uncertain whether a given XPointer will locate something, you can back it up with an alternative XPointer. For example, this XPointer looks first for first_name elements. However, if it doesn't find any it will look for last_name elements instead: xpointer(//first_name)xpointer(//last_name) The last_name elements will be found only if there are no first_name elements. You can string as many of these xpointer() parts together as you like. For example, this XPointer looks first for first_name elements. If it doesn't find any, it then seeks out last_name elements. If it doesn't find any of those, it looks for middle_initial elements. If it doesn't find any of those, it returns an empty node set: xpointer(//first_name)xpointer(//last_name)xpointer(//middle_initial) No special separator character or white space is required between the individual xpointer() parts. {185} In the second code fragment on the page, each XPath expression should be preceded by here(). That is, the entire example and the paragraph that follows should read as follows: Acme Wonder Goo is a delicious dessert topping! Acme Wonder Goo is a powerful floor cleaner! It's two products in one! Back Back The here() function, an XPointer extension to XPath, indicates that the context node is the node in the XML document where the XPointer appears, the xlink:href attribute nodes in this example. [187] Delete all text from the paragraph beginning "To point at a point with an XPointer..." to the end of the section and replace it with: The point() node test can be used to select points from a node set that contains them. However, since no XPath axis actually includes points, this has limited utility. Instead, XPointer adds two functions to XPath that make it very easy to select the point immediately before or immediately after an element or text node, start-point() and end-point(). For example, this XPointer identifies the point immediately before the title element, point 1 in Figure 11-1: xpointer(start-point(//title)) This XPointer indicates the point immediately after the tag: xpointer(end-point(//author)) If there were multiple title and author elements in the document, then these functions would select multiple points. Points can also indicate positions inside a text node, comment, attribute value, or processing instruction. This is less convenient than it should be. First you'll need to use the string-range() function we'll discuss shortly to produce a range whose start point or end point is the point you want to select; then use start-point() and end-point() to actually select that point. In each case, the point's position is the index of the character following the point in the node's string value. Recall from Chapter 8 that the value of a comment node is the text of the comment, the value of an attribute node is the value of the attribute, and the value of a processing instruction node is the processing instruction data. For example, suppose you want to indicate the point right before the word may in . The letter m is the sixth character of the value of the comment. Therefore the point immediately before it has index 5. Processing instructions are similar except you don’t count the processing instruction target or subsequent white space. For example, suppose you wanted to point to the point between the " and the n in "novel.css". The " is the 23rd character of the data and the n is the 24th. Processing instructions can only have pseudo-attributes so you can’t use the attribute axis to select the value "attribute" of the xml-stylesheet processing instruction or any points inside it. However, you can do this for genuine attributes like the copyright attribute of the novel element in Example 11-1. In all cases, it's an error if a point() node test points before the beginning of the containing node (i.e. has a negative index) or after the end of the containing node. However, an application is free to decide what to do in the face of such an error. No specific behavior is required. In a web browser the results might be similar to following a link to a named anchor that no longer exists; that is, the document would be loaded and positioned at its start and the fragment identifier would be ignored. {212}: There's an extra fo:region-body element in the second code fragment on the page. Delete the fifth line containing the start-tag. That is, the fragment should read: [219] Example 13-5; Replace example. Southern Corn Bread ’Ä¢ 1 cup flour ’Ä¢ 4 tablespoons Royal Baking Powder ’Ä¢ ¬‡ teaspoon salt ’Ä¢ 1 cup corn meal ’Ä¢ 1¬‡ cups whole milk ’Ä¢ 4 tablespoons melted butter Sift flour, baking powder, sugar & salt together. Add 1 cup corn meal. Beat egg in cup and add beaten egg and 1¬‡ cups whole milk to make a batter. Stir well. Add melted shortening and beat until light and thoroughly mixed. Pour into greased shallow pan or greased muffin rings. Bake in hot oven at 425¬† F for 25 minutes. Cut into squares if cooked in shallow pan. After my mother-in-law Marjorie Anderson died, Beth and I found this recipe written on the "extra recipes" page in a local cookbook in her cupboard. This was published by The Episcopal Churchwomen, Church of Ascension, Mt. Sterling, Kentucky. (237) In the first line, "Java inteface" should be "Java interface". {239} Figure 16-1; nodeValue =Text data in the "Text" box should be nodeValue =Test data {251}: SAXException is a checked exception, not a runtime exception. In the second text paragraph change "runtime" to "checked". {260}: When reading a property a cast is normally necessary. The last code fragment on the page should read: try { String tag = (String) parser.getProperty( "http://xml.org/sax/properties/xml-string"); } (281) In the penultimate paragraph; "characters are not be recognized as markup by the parser" should read "characters will not be recognized as markup by the parser". {302} In the examples of abbreviated syntax in the last code fragment on the page, "//descendantnode() [.='Eunice']/@ID" is missing a double-colon separator and should read: "//descendant::node() [.='Eunice']/@ID" (305) In the first sentence change "Each location test" to "Each location step" (320) In the Contents section for xsl:choose, "This element contains one xsl:when element" should read "This element contains one or more xsl:when elements" {373} The example for getAttribute() is incorrect. if (elem.getAttribute("name") == "") { should be if (elem.getAttribute("name").equals("")) { (477) In the index: The Vietnamese language entry has an uppercase 'I' as the second letter. The 'I', of course, should be lowercase.