The purpose of an extensible style sheet is to better display the values of an XML document. The primary object that holds a value in an XML document is an XML element. This means that you must "transform" an element to display its value. In the XSLT document, specify what value to display and when. To do this, in the body section, create an element named value-of. The syntax of the value-of element is: <xsl:value-of select = Expression disable-output-escaping = "yes" | "no" </xsl:value-of> The element must have an attribute named select that holds an expression that the parser must follow to identify an element. If you specify the match value of the template element as the name of the root, the value of the select attribute of the value-of element can be the name of an element that is a child of the root. Here is an example: <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="videos"> <html> <head> <title>Video Collection</title> </head> <body> <div align="center"> <h2><xsl:value-of select="DocumentTitle" /></h2> </div> </body> </html> </xsl:template> </xsl:stylesheet> This would produce:
If you specify the match value of the template element as "/", if you want to access an element that is a child of the root, precede its name with the name of the root for the value of the select attribute of the value-of element. The above document is the same as: <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <head> <title>Real Estate - Properties Listing</title> </head> <body> <div align="center"> <h2><xsl:value-of select="videos/introduction" /></h2> </div> </body> </html> </xsl:template> </xsl:stylesheet> This would produce the same result as previously. In the same way, you can select other values from the XML document. Here are examples: <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <head> <title>Video Collection</title> </head> <body> <div align="center"> <h2><xsl:value-of select="videos/DocumentTitle" /></h2> <h3><xsl:value-of select="videos/introduction" /></h3> </div> </body> </html> </xsl:template> </xsl:stylesheet> This would produce:
Another technique consists of creating one or a series of templates and applying them in the desired section(s). In this case, create a template for each element. In the area where you want to use the format(s), create an XSLT element named apply-templates. The syntax of the apply-templates element is: <xsl:apply-templates select = Expression mode = QName </xsl:apply-templates> Both attributes are optional. Here is an example: <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> <xsl:template match="/videos"> <html> <head> <title>Video Collection</title> </head> <body> <div align="center"> <xsl:apply-templates /> </div> </body> </html> </xsl:template> <xsl:template match="DocumentTitle"> <h2><xsl:value-of select="." /></h2> </xsl:template> <xsl:template match="introduction"> <h3><xsl:value-of select="." /></h3> </xsl:template> </xsl:stylesheet> If you want to provide the nodes that the parser must consider, pass them in the select attribute. The mode is used by the parser to process an element multiple times. In this case, pass the name of the element to this attribute.
Instead of transforming one element at a time, you may have a series of elements and it would not be flexible to visit each element. In fact. it may be impossible to visit each element if the list of elements can grow or shrink any time. If the elements are child nodes, you can apply a loop to their parent and visit each child node. To support this operation, XSLT provides an element named for-each. The formula to use the for-each element is: <xsl:for-each select = Expression </xsl:for-each> As done for the elements so far, the select attribute allows you to specify the element to use. This is a typical list to which new elements (new houses in this case) can be added any time and undesired elements (such as sold houses) can be deleted any time. So it is not practical to visit each node. In fact, elements on the same level may not have the same child nodes and child nodes may not be arranged in the same order in each element. You can first create an XSLT file or section with a placeholder for each element. Here is an example: <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <head> <title>Video Collection</title> </head> <body> <h2>Video Collection</h2> <table> <tr> <td><b>Title</b></td> <td><b>Director</b></td> <td><b>Format</b></td> <td><b>Rating</b></td> </tr> <tr> <td>Placeholder for title</td> <td>Placeholder for director</td> <td>Placeholder for format</td> <td>Placeholder for rating</td> </tr> </table> </body> </html> </xsl:template> </xsl:stylesheet> A solution is to use a for-each element to visit each child node. This can be done as follows: <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <head> <title>Video Collection</title> </head> <body> <div align="center"> <h2>Video Collection</h2> <table> <tr style="background-color: #B8B8B8"> <td> <b>Title</b> </td> <td> <b>Director</b> </td> <td> <b>Format</b> </td> <td> <b>Rating</b> </td> </tr> <xsl:for-each select ="videos/video"> <tr style="background-color: #E2E2E2"> <td> <xsl:value-of select="title" /> </td> <td> <xsl:value-of select="director" /> </td> <td> <xsl:value-of select="format" /> </td> <td> <xsl:value-of select="rating" /> </td> </tr> </xsl:for-each> </table> </div> </body> </html> </xsl:template> </xsl:stylesheet> This would produce:
As you may know already, an XML atribute is a child element created inside of the start tag of a node. Here is an example of an XML document with attributes: <?xml version="1.0" encoding="utf-8" ?> <videos common-name="Video Collection" purpose="To keep track of personal/home videos"> <video shelf-number="PLT24857"> <title France="Monsieur le Député" Italy="Il Distinto Gentiluomo" Spain="Su Distinguida Señoría" Croatia="Ugledni gospodin">The Distinguished Gentleman</title> <director>Jonathan Lynn</director> <length>112</length> <format screen="Wide Screen">DVD</format> <rating>R</rating> <year-released date-released="4 December 1992">1992</year-released> </video> <video shelf-number="SCF13948"> <title Spain="El Día de Mañana" Croatia="Dan Poslije Sutra" Portugal="O Dia Depois de Amanhã" France="Le jour d'après">The Day After Tomorrow</title> <director>Roland Emmerich</director> <length>124</length> <format>BD</format> <rating>PG-13</rating> </video> </videos> Because an attribute is related to its parent element, to access an attribute in an extensible style sheet, precede its name with the @ sign, but you must indicate its parent element. This can be done in the template element where you would provide the name of its parent element. Here is an example: <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="video"> <html> <head> <title>Video Collection</title> </head> <body> <div align="center"> <xsl:value-of select="@shelf-number" /> </div> </body> </html> </xsl:template> </xsl:stylesheet> This wiykd produce:
In the same way, you can transform other XML attributes from your style sheet. Also you can format the values of the attributes any way you want. Here is an example: <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="title"> <html> <head> <title>Video Collection</title> </head> <body> <p>Spanish Title: <xsl:value-of select="@Spain" /></p> </body> </html> </xsl:template> </xsl:stylesheet> This would produce:
If you have different elements that have attributes, you can specify the value of the match attribute of the template as the root or an ancestor. To access an attribute, use the following formula: ParentElement/@AttributeName Here are example: <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="video"> <html> <head> <title>Video Collection</title> </head> <h2>Video Collection</h2> <body> <p>Spanish Title: <xsl:value-of select="title/@Spain" /></p> <p>French Title: <xsl:value-of select="title/@France" /></p> <p>Portuguese Title: <xsl:value-of select="title/@Portugal" /></p> </body> </html> </xsl:template> </xsl:stylesheet> This would produce:
In the same, you can visit the attributes in an element using for-each and accessing each of them using the @ sign. Here are examples: <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <head> <title>Video Collection</title> </head> <h2>Video Collection</h2> <body> <xsl:for-each select="videos/video"> <span>Video Title: <xsl:value-of select="title/@Spain" /><br /></span> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet> This would produce:
In the XSLT standards, the formula to transform an attribute is: <xsl:attribute name = "attribute-name" namespace = "uri-reference"> </xsl:attribute> The name attribute is required. It can be a qualified or a local name. The namespace attribute is the address that defines where the transformating attribute was defined. |
|
|||||||||||
|