Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 76 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
76
Dung lượng
147,63 KB
Nội dung
<xsl:import href="tree-control.xslt"/> <xsl:param name="collapse"/> <xsl:variable name="collapse-test" select="concat(' ',$collapse,' ')"/> <xsl:template match="*" mode="name"> <xsl:if test="not(ancestor::*[contains($collapse-test, concat(' ',local- name(.),' '))])"> <xsl:apply-imports/> </xsl:if> </xsl:template> <xsl:template match="*" mode="value"> <xsl:if test="not(ancestor::*[contains($collapse-test, concat(' ',local- name(.),' '))])"> <xsl:apply-imports/> </xsl:if> </xsl:template> <xsl:template match="*" mode="line-break"> <xsl:if test="not(ancestor::*[contains($collapse-test, concat(' ',local- name(.),' '))])"> <xsl:apply-imports/> </xsl:if> </xsl:template> <xsl:template match="*" mode="indent"> <xsl:choose> <xsl:when test="self::*[contains($collapse-test, concat(' ',local- name(.),' '))]"> <xsl:for-each select="ancestor::*"> <xsl:text> </xsl:text> </xsl:for-each> <xsl:text> x-</xsl:text> </xsl:when> <xsl:when test="ancestor::*[contains($collapse-test, concat(' ',local-name(.),' '))]"/> <xsl:otherwise> <xsl:apply-imports/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> Example 5-34. Output with $collapse="Employee PayPeriod" o-[ExpenseReport] x-[Employee] x-[PayPeriod] o-[Expenses] o-[Expense] | +-[Date] 12/20/01 | +-[Account] 12345 | +-[Desc] Goofing off instead of going to confrence. | +-[Lodging] 500.00 | +-[Transport] 50.00 | +-[Fuel] 0 | +-[Meals] 300.00 | +-[Phone] 100 | +-[Entertainment] 1000.00 | `-[Other] 300.00 o-[Expense] +-[Date] 12/20/01 +-[Account] 12345 +-[Desc] On the beach +-[Lodging] 500.00 +-[Transport] 50.00 +-[Fuel] 0 +-[Meals] 200.00 +-[Phone] 20 +-[Entertainment] 300.00 `-[Other] 100.00 There is literally no end to the variety of custom tree formats you can create from overrides to the basic stylesheet. In object-oriented circles, this technique is called the template-method pattern. It involves building the skeleton of an algorithm and allowing subclasses to redefine certain steps without changing the algorithm's structure. In the case of XSLT, importing stylesheets take the place of subclasses. The power of this example does not stem from the fact that creating tree-like rendering is difficult; it is not. Instead, the power lies in the ability to reuse the example's structure while considering only the aspects you want to change. 5.5 Numbering Textual Output 5.5.1 Problem You want to create sequentially numbered output. 5.5.2 Solution Since output can be numbered in many ways, this example presents a series of increasingly complex examples that address the most common (and a few uncommon) numbering needs. 5.5.2.1 Number siblings sequentially This category is the simplest form of numbering. For example, you can produce a numbered list of people using the stylesheet in Example 5-35 and Example 5-36. Example 5-35. Stylesheet <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="person"> <xsl:number count="*" format="1. "/> <xsl:value-of select="@name"/> </xsl:template> </xsl:stylesheet> Example 5-36. Output 1. Al Zehtooney 2. Brad York 3. Charles Xavier 4. David Willimas 5. Edward Ulster 6. Frank Townsend 7. Greg Sutter 8. Harry Rogers 9. John Quincy 10. Kent Peterson You can use the justify template discussed in Recipe 5.3 if you want right-justified numbers. 5.5.2.2 Start from a number other than one xsl:number does not provide a standard facility for starting from or incrementing by a number other than one, but you can handle this task with a little math. Example 5-37 and Example 5-38 start from ten and increment by five, just to be different. Example 5-37. Stylesheet using nonsequential numbering <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="person"> <xsl:variable name="num"> <xsl:number count="*"/> </xsl:variable> <xsl:number value="($num - 1) * 5 + 10" format="1. "/> <xsl:value-of select="@name"/> <xsl:text>
</xsl:text> </xsl:template> </xsl:stylesheet> Example 5-38. Output 10. Al Zehtooney 15. Brad York 20. Charles Xavier 25. David Willimas 30. Edward Ulster 35. Frank Townsend 40. Greg Sutter 45. Harry Rogers 50. John Quincy 55. Kent Peterson This scenario works even if you want the final output to use a non-numerical format. For example, Example 5-39 and Example 5-40 use the same technique to start numbering at L. Example 5-39. Stylesheet for numbering from L <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="person"> <xsl:variable name="num"> <xsl:number count="*"/> </xsl:variable> <xsl:number value="$num + 11" format="A. "/> <xsl:value-of select="@name"/> <xsl:text>
</xsl:text> </xsl:template> </xsl:stylesheet> Example 5-40. People numbered successively from letter L L. Al Zehtooney M. Brad York N. Charles Xavier O. David Willimas P. Edward Ulster Q. Frank Townsend R. Greg Sutter S. Harry Rogers T. John Quincy U. Kent Peterson 5.5.2.3 Number elements globally Sometimes you want to number elements sequentially without regard to their context. The most common example involves a document that contains footnote elements. The footnotes can appear at any level in the document's structure, yet they should be numbered sequentially. However, to continue the theme of your example, here is a document that divides people into various groups and subgroups: <people> <group> <person name="Al Zehtooney" age="33" sex="m" smoker="no"/> <person name="Brad York" age="38" sex="m" smoker="yes"/> <person name="Charles Xavier" age="32" sex="m" smoker="no"/> <person name="David Willimas" age="33" sex="m" smoker="no"/> <person name="Edward Ulster" age="33" sex="m" smoker="yes"/> <person name="Frank Townsend" age="35" sex="m" smoker="no"/> </group> <group> <person name="Greg Sutter" age="40" sex="m" smoker="no"/> <person name="Harry Rogers" age="37" sex="m" smoker="no"/> <group> <person name="John Quincy" age="43" sex="m" smoker="yes"/> <person name="Kent Peterson" age="31" sex="m" smoker="no"/> <person name="Larry Newell" age="23" sex="m" smoker="no"/> <group> <person name="Max Milton" age="22" sex="m" smoker="no"/> <person name="Norman Lamagna" age="30" sex="m" smoker="no"/> <person name="Ollie Kensinton" age="44" sex="m" smoker="no"/> </group> <person name="John Frank" age="24" sex="m" smoker="no"/> </group> <group> <person name="Mary Williams" age="33" sex="f" smoker="no"/> <person name="Jane Frank" age="38" sex="f" smoker="yes"/> <person name="Jo Peterson" age="32" sex="f" smoker="no"/> <person name="Angie Frost" age="33" sex="f" smoker="no"/> <person name="Betty Bates" age="33" sex="f" smoker="no"/> <person name="Connie Date" age="35" sex="f" smoker="no"/> <person name="Donna Finster" age="20" sex="f" smoker="no"/> </group> <group> <person name="Esther Gates" age="37" sex="f" smoker="no"/> <person name="Fanny Hill" age="33" sex="f" smoker="yes"/> <person name="Geta Iota" age="27" sex="f" smoker="no"/> <person name="Hillary Johnson" age="22" sex="f" smoker="no"/> <person name="Ingrid Kent" age="21" sex="f" smoker="no"/> <person name="Jill Larson" age="20" sex="f" smoker="no"/> <person name="Kim Mulrooney" age="41" sex="f" smoker="no"/> <person name="Lisa Nevins" age="21" sex="f" smoker="no"/> </group> </group> </people> The only necessary change is to use the xsl:number attribute level="any". This attribute instructs the XSLT processor to consider all preceding occurrences of the person element when determining numbering. See Example 5-41 and Example 5-42. Example 5-41. Stylesheet for level="any" <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="person"> <xsl:number count="person" level="any" format="1. "/> <xsl:value-of select="@name"/> <xsl:text>
</xsl:text> </xsl:template> </xsl:stylesheet> Example 5-42. Output with level="any" 1. Al Zehtooney 2. Brad York 3. Charles Xavier 4. David Willimas 5. Edward Ulster 6. Frank Townsend 7. Greg Sutter 8. Harry Rogers 9. John Quincy 10. Kent Peterson 11. Larry Newell 12. Max Milton 13. Norman Lamagna 14. Ollie Kensinton 15. John Frank 16. Mary Williams 17. Jane Frank 18. Jo Peterson 19. Angie Frost 20. Betty Bates 21. Connie Date 22. Donna Finster 23. Esther Gates 24. Fanny Hill 25. Geta Iota 26. Hillary Johnson 27. Ingrid Kent 28. Jill Larson 29. Kim Mulrooney 30. Lisa Nevins 5.5.2.4 Number elements globally within a subcontext Sometimes you want to restrict global numbering to a specific context. For example, suppose you want to number people within their top-level group and ignore subgroups: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="people/group"> <xsl:text>Group </xsl:text> <xsl:number count="group"/> <xsl:text>
</xsl:text> <xsl:apply-templates/> <xsl:text>
</xsl:text> </xsl:template> <xsl:template match="person"> <xsl:number count="person" level="any" from="people/group" format="1. "/> <xsl:value-of select="@name"/> <xsl:text>
</xsl:text> </xsl:template> </xsl:stylesheet> Group 1 1. Al Zehtooney 2. Brad York 3. Charles Xavier 4. David Willimas 5. Edward Ulster 6. Frank Townsend Group 2 1. Greg Sutter 2. Harry Rogers 3. John Quincy 4. Kent Peterson 5. Larry Newell 6. Max Milton 7. Norman Lamagna 8. Ollie Kensinton 9. John Frank 10. Mary Williams 11. Jane Frank 12. Jo Peterson 13. Angie Frost 14. Betty Bates 15. Connie Date 16. Donna Finster 17. Esther Gates 18. Fanny Hill 19. Geta Iota 20. Hillary Johnson 21. Ingrid Kent 22. Jill Larson 23. Kim Mulrooney 24. Lisa Nevins 5.5.2.5 Number hierarchically In formal and legal documents, items are often numbered based on both their sequence and level within a hierarchy. As shown in Example 5-43 to Example 5-45, xsl:number supports this via attribute level="multiple". Example 5-43. Hierarchical numbering based on group and person <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="people/group"> <xsl:text>Group </xsl:text> <xsl:number count="group"/> <xsl:text>
</xsl:text> <xsl:apply-templates/> <xsl:text>
</xsl:text> </xsl:template> <xsl:template match="person"> <xsl:number count="group | person" level="multiple" format="1.1.1 "/> <xsl:value-of select="@name"/> <xsl:text>
</xsl:text> </xsl:template> </xsl:stylesheet> The numbering achieved by the stylesheet in Example 5-45 is somewhat odd, but it effectively illustrates the effect of attribute count when it is used with level = "multiple". The count attribute is simply a specification for determining what ancestor elements should be included when composing a hierarchical number. The stylesheet assigned numbers to people based on group or person elements. Bard York is assigned 1.2 because he is in Group 1 and is the second person in the group. Likewise, Max Milton is assigned 2.3.4.1 because he is in Group 2 when considering only top-level groups; he is in Group 3 when considering both top- and second- level groups; he is in Group 4 when considering all top-, second-, and third-level groups; and he is the first person within his own group: Group 1 1.1 Al Zehtooney 1.2 Brad York 1.3 Charles Xavier 1.4 David Willimas 1.5 Edward Ulster 1.6 Frank Townsend Group 2 2.1 Greg Sutter 2.2 Harry Rogers 2.3.1 John Quincy 2.3.2 Kent Peterson 2.3.3 Larry Newell 2.3.4.1 Max Milton 2.3.4.2 Norman Lamagna 2.3.4.3 Ollie Kensinton 2.3.5 John Frank 2.4.1 Mary Williams 2.4.2 Jane Frank 2.4.3 Jo Peterson 2.4.4 Angie Frost 2.4.5 Betty Bates 2.4.6 Connie Date 2.4.7 Donna Finster 2.5.1 Esther Gates 2.5.2 Fanny Hill 2.5.3 Geta Iota 2.5.4 Hillary Johnson 2.5.5 Ingrid Kent 2.5.6 Jill Larson 2.5.7 Kim Mulrooney 2.5.8 Lisa Nevins In typical applications, you expect a numbering scheme in which the number at any level is relative to the number at the next higher level. You can achieve this relationship by using multiple and adjacent xsl:number elements, as shown in Example 5-44 and 5-45. Example 5-44. Stylesheet for creating muliple ordered levels <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="group"> <xsl:text>Group </xsl:text> <xsl:number count="group" level="multiple"/> <xsl:text>
</xsl:text> <xsl:apply-templates/> </xsl:template> <xsl:template match="person"> <xsl:number count="group" level="multiple" format="1.1.1."/> <xsl:number count="person" level="single" format="1 "/> <xsl:value-of select="@name"/> <xsl:text>
</xsl:text> </xsl:template> </xsl:stylesheet> Example 5-45. Output Group 1 1.1 Al Zehtooney 1.2 Brad York 1.3 Charles Xavier 1.4 David Willimas 1.5 Edward Ulster 1.6 Frank Townsend Group 2 [...]... version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" id="text.wrap" xmlns:str="http://www.ora.com/XSLTCookbook/namespaces/string s" xmlns:text="http://www.ora.com/XSLTCookbook/namespaces/text" exclude-result-prefixes="text"> 6 .4 Merging Documents with Identical Schema 6 .4. 1 Problem You have two or more identically structured... stylesheet defines uniqueness of elements in terms of a key > ... Larry Newell Group 2.1.1 2.1.1.1 Max Milton 2.1.1.2 Norman Lamagna 2.1.1.3 Ollie Kensinton 2.1 .4 John Frank Group 2.2 2.2.1 Mary Williams 2.2.2 Jane Frank 2.2.3 Jo Peterson 2.2 .4 Angie Frost 2.2.5 Betty Bates 2.2.6 Connie Date 2.2.7 Donna Finster Group 2.3 2.3.1 Esther Gates 2.3.2 Fanny Hill 2.3.3 Geta Iota 2.3 .4 Hillary Johnson 2.3.5 Ingrid Kent 2.3.6 Jill Larson 2.3.7 Kim Mulrooney 2.3.8 Lisa Nevins... 6-15 A stylesheet defining what element equality means . Norman Lamagna 2.3 .4. 3 Ollie Kensinton 2.3.5 John Frank 2 .4. 1 Mary Williams 2 .4. 2 Jane Frank 2 .4. 3 Jo Peterson 2 .4. 4 Angie Frost 2 .4. 5 Betty Bates 2 .4. 6 Connie Date 2 .4. 7 Donna Finster. relationship by using multiple and adjacent xsl:number elements, as shown in Example 5 -44 and 5 -45 . Example 5 -44 . Stylesheet for creating muliple ordered levels <xsl:stylesheet version="1.0". attribute instructs the XSLT processor to consider all preceding occurrences of the person element when determining numbering. See Example 5 -41 and Example 5 -42 . Example 5 -41 . Stylesheet for level="any"