Generating dynamic web pages using XSL and XMLIn an earlier article, 'Using XSL and XML to generate dynamic web pages from UNIFACE', I demonstrated how it is possible to generate web pages using XSL to transform XML documents into HTML for output to the web. This replaces the UNIFACE- specific method of web page generation with a standard method that is supported by the World Wide Web Consortium and which gained popularity with the Apache Cocoon Project. In this follow- up article I will show you samples of web pages and explain the XSL stylesheets that I used to transform the XML data. I have put together a set of PHP scripts which you can access here on my website which will show these techniques in action. These are described in A Sample PHP Application. The complete source code can be downloaded from here so you can see how it is achieved. Note: An updated version of this document called Reusable XSL Stylesheets and Templates shows how to avoid the need to have customised versions of each XSL stylesheet which contain hard- coded field names. By passing the list of fields to be displayed within the XML data it is possible to use the same XSL stylesheet for many different screens. This consists of an initial parent form and a series of child forms, as shown in Figure 1. 2.4 Executing a Transformation [Definition: A stylesheet contains a set of template rules (see 6 Template Rules). A template rule has three parts: a pattern that is matched against nodes, a. I have an XML document, and I want to change the values for one of the attributes. First I copied everything from input to output using: <xsl:template match='@*|node()'> <xsl:copy>. Definition and Usage. The <xsl:template> element contains rules to apply when a specified node is matched. The match attribute is used to associate the template with an XML element. The match attribute can also be used to. Originally written by Benoît Marchal. XML concentrates on the structure of the information in a file and not its appearance. To view XML documents we need to format or style them. In practice, this often means converting the. Select node by attribute value. File: Data.xml <?xml version='1.0'?> <employees> <employee eid='98145' dept='programming'> <title>Java Programmer</title> <contact addInfo='info1'> <name> <firstName>Joe. I am just learning XML and how to use XSL files. In an XSL file I found the following term: xsl:template match='/' What does this stand for? And what could I use instead of the /? Could I write. This specification defines the syntax and semantics of XSLT, which is a language for transforming XML documents into other XML documents. (W3C Recommendation 16 November 1999). Xsl Template Match Node Attributes1. Introduction. In an earlier article, 'Using XSL and XML to generate dynamic web pages from UNIFACE', I demonstrated how it is possible to generate web pages using XSL to transform XML documents into HTML for output to the. Www.xmlplease.com > XSLT. Jesper Tverskov, July 27, 2005. Identity Template: xsl:copy with recursion. The so-called identity template that copies everything from input.xml to output.xml, element for element, attribute for. The <xsl:template> Element. The <xsl:template> element is used to build templates. The match attribute is used to associate a template with an XML element. The match attribute can also be used to define a template for the. The parent form may be accessed through a menu mechanism, but a child form can only be accessed through a parent form. This is because some form of context may need to be exchanged between the parent and the child. The LIST form will allow the user to browse through occurrences on a database table. The user can then select one or more of the displayed occurrences before activating one of the child forms. The INSERT form will allow the user to insert a new occurrence on the database table. The UPDATE form will allow the user to modify an occurrence selected from the LIST form. The DELETE form will allow the user to delete an occurrence selected from the LIST form. The ENQUIRE form will allow the user to enquire in more detail on an occurrence selected from the LIST form. The SEARCH form will allow the user to specify new search criteria for the LIST form. This is a typical arrangement of simple, single- function components that I have been using in client/server systems for many years, and which just happens to be the recommended approach when designing components for the web. The following are a series of screen shots from my demonstration system. I built these using a combination of PHP and My. SQL running under the Apache web server (refer to A Sample PHP Application for details), but the techniques can be employed in any development language that can create XML files and has access to an XSL Transform engine. You may notice that these screens are devoid of any fancy graphics - this is entirely deliberate as I am concentrating on the functionality, not the cosmetics. Fancy gimmicks, gizmos and doo- dads can be added in by anyone competent in HTML simply by modifying the HTML code in the XSL stylesheet, or by modifying the CSS file. Any customisation of the Presentation layer can therefore be carried out without affecting any component in the Business layer. Figure 2 shows a form that lists occurrences from the PERSON table. As there may be more occurrences that can fit comfortably into the screen they are divided into 'pages' where each page will contain a maximum number of occurrences. Hyperlinks at the bottom the screen will allow the user to jump to different pages. There is also an area for standard 'action' buttons and an area for optional 'navigation' buttons. Each of these areas is explained in more detail in Figure 3. Figure 3 identifies and explains each of the different areas within the LIST screen shown in Figure 2. Area 1 is the first line of the menu bar and contains a hyperlink for each option within the current menu. If an option which is another menu is selected then the entire contents of this line will change. If a non- menu option is selected then all the areas below the menu bar will change to reflect the requirements of that option, and the background colour of the menu tab will change to the same colour as the second line of the menu bar (area 2). Area 2 is the second line of the menu bar and contains hyperlinks which trace the route from the home page to the current page. This area is sometimes known as 'breadcrumbs' as it allows the user to trace his/her way back home if he/she gets lost. Options which are currently active will not be presented as hyperlinks. Area 3 contains the form title. This is not hard- coded into the XSL stylesheet, it is passed as a parameter to the XSL Transform process. Area 4 is the first line of the navigation bar and contains buttons which will activate other pages (such as NEW or SEARCH) without the need for any rows in the current display to be selected (refer to area 8). The NEW button will bring up a blank detail screen which will allow the user to create a new database occurrence. The SEARCH button will bring up a blank screen which will the allow the user to define selection criteria before a fresh set of details are retrieved from the database. Area 5 is the second line of the navigation bar and contains two sections. On the left it has hyperlinks named 'select all' and 'unselect all' which act upon all the checkboxes in area 8. On the right it has hyperlinks named 'show nn' which will alter the number of rows within each page (area 9). This will also have an effect on the contents of the pagination area (area 1. Area 6 is the third line of the navigation bar and contains buttons that will activate a different child form. These buttons require that one or more occurrences in area 9 be pre- selected by setting the associated checkbox in area 8. This selection process enables the primary key(s) of the selected occurrence(s) to be passed down to the child form so that they know which occurrences to process. Upon returning from a child function the parent function will re- retrieve its data according to the current settings (page number, sort sequence, etc). This is so that any changes made by the child function can be included in the screen display. Area 7 contains the column headings for the data table. Apart from 'SELECT' the column headings are defined as hyperlinks which will allow the page to be regenerated and sorted on that column. The sort sequence will alternate between ascending and descending, as indicated by an 'up' or 'down' arrow next to the selected column. Any sort options can be reset by pressing the appropriate button in the action bar (area 1. Area 8 contains a separate checkbox for each occurrence retrieved from the database (area 9). This is used to select an occurrence for subsequent processing by a child form which can be activated by pressing one of the buttons in the navigation bar (area 6). Area 9 contains the body of the data table. Each horizontal line/row will show data from a different database occurrence, with the odd and even numbered rows shown in different colours. The SELECT column allows a particular row to be chosen for further processing. Area 1. 0 is an optional area that will show any messages that have been generated. Area 1. 1 is for pagination. It shows the current page number and the total number of pages. Depending on the current page number the FIRST, PREV, NEXT and LAST words will become hyperlinks, allowing the user to jump to the designated page number. Area 1. 2 contains action buttons which are usually constant for each type of screen. CANCEL or CLOSE will return to the previous screen while SUBMIT will post any changed data to the web server so that it may update the database. The RESET button will cancel any selection and sorting criteria, then rebuild the screen from page 1. Certain screens may also contain buttons to COPY or PASTE. Area 1. 3 is appended to the action bar and shows how long it took for the request to be processed. The value is calculated by the business layer component and passed as a parameter to the XSL Transform process. Each of these areas is processed by a different set of stylesheet instructions, as will be explained later. The INSERT form allows the user to enter the details for a new occurrence. Required fields are indicated with an asterisk in front of the field label. The SUBMIT button will cause the data to be added to the database (provided that all validation rules are satisfied), then it will return to the previous screen. The COPY+SUBMIT button will copy the current data into memory so that it is available for the PASTE button. The CANCEL button will ignore any entered data and return to the previous screen. Validation errors are dealt with as shown in Figure 5. Any error message for a particular field will be displayed underneath that field's input area. If an error cannot be associated with a particular field then it will be displayed in the message area at the bottom of the screen (area 1. Figure 3). This will display the current values for the occurrence selected in the previous screen, then allow the user to make changes. Validation errors will be dealt with as shown in Figure 5. The COPY button will allow the current data to be saved in memory so that it can be included into an INSERT screen with the PASTE button. This will display the selected occurrence and allow the user to either confirm or cancel the deletion. If the current occurrence cannot be deleted an appropriate message will be displayed and the SUBMIT button will not be shown. The COPY button will allow the current data to be saved in memory so that it can be included into an INSERT screen with the PASTE button. This will display the current values for the occurrence selected in the previous screen. The COPY button will allow the current data to be saved in memory so that it can be included into an INSERT screen with the PASTE button. This will allow the user to specify different selection criteria to be used by the LIST screen. Identity Template: xsl: copy with recursionwww. XSLTJesper Tverskov, July 2. The so- called identity template that copies everything from input. The "identity" template was introduced with an example in the XSLT Recommendation itself: [1]< xsl: templatematch="@*|node()"> В В < xsl: copy> В В В В < xsl: apply- templatesselect="@*|node()"/> В В < /xsl: copy> < /xsl: template> In this tutorial we will look at the very basics of "xsl: copy with recursion". More advanced examples can be found in XSLT books of the "cookbook" type. Identity: Copy with recursion. The above template copies all attributes, @*, and all nodes being children of other nodes, node(): element nodes, text nodes, comment nodes and processing instruction nodes. Everything is copied. Recursion" in the above case is when the template ends its job by calling other templates including itself. Copying everything is no fun but becomes very useful when we add exceptions to the copying. It gets useful when we "copy everything but". The step by step approach in the copying is the big trick. For each attribute, element, etc., we can decide to do something else by adding other templates overruling the copying behavior. Better tutorials for beginners. Many books and tutorials about XSLT mention the "identity" or "copy with recursion" template. But most users of XSLT never get to use it for real, because they don't understand it. Most XSLT beginners are not at ease with node(), xsl: copy and xsl: apply- templates and even less with the "identity template" using all three. Beginners get fast into the habit of using less elegant and less efficient methods to achieve the same thing as copying with recursion. Most often xsl: copy- of is used for parts of the transformation and major parts of XML output is recreated the hard way, "by hand". When beginners get more experienced, they most often continue the bad habit of ignoring "copy with recursion". Today when XML file formats in MS Office 2. XML to the masses, we need more user friendly XSLT books and tutorials. Users of XSLT now include power users of Office applications with little programming experience. Node()" is shorthand for child: :node(). That is node() matches all nodes (element, text, comment, processing- instruction) being children of other nodes but not attributes since they are not considered children of their parent element. To find all nodes in order to copy them, we need to match both nodes being children of other nodes, node(), and attributes, @*, that is: match="@*|node()". Instead of the traditional shorthand way of writing the match expression, we could write: match="@*|*|text()|comment()|processing- instruction()"Or even better in XSLT/XPath 2. The last "match" makes it more clear what is happening. The most common processing instruction is for adding an XSLT stylesheet and could look like this: < ? We will ignore PIs in the following. Input. xml. In the examples we will use this file as xml input: < ? Jesper"> В В < productid="p. В В В В < name> Delta< /name> В В В В < price> 8. В В В В < stock> 4< /stock> В В В В < country> Denmark< /country> В В < /product> В В < productid="p. В В В В < name> Golf< /name> В В В В < price> 1. В В В В < stock> 5< /stock> В В В В < country> Germany< /country> В В < /product> В В < productid="p. В В В В < name> Alfa< /name> В В В В < price> 1. В В В В < stock> 1. В В В В < country> Germany< /country> В В < /product> В В < productid="p. В В В В < name> Foxtrot< /name> В В В В < price> 1. В В В В < stock> 5< /stock> В В В В < country> Australia< /country> В В < /product> < !- - p. В В < productid="p. В В В В < name> Tango< /name> В В В В < price> 1. В В В В < stock> 3< /stock> В В В В < country> Japan< /country> В В < /product> < /products> 5. Not some attributes. Stylesheet. xslt< xsl: templatematch="@*|node()"> В В < xsl: copy> В В В В < xsl: apply- templatesselect="@*|node()"/> [3]В В < /xsl: copy> < /xsl: template> < xsl: templatematch="@id"/> The first template matches all attributes and all nodes being children of other nodes, and copies them over. The second template matches the id attribute of the context element. The first template puts node after node in context making it possible for the second template to find the id attributes. The second template cancels the copying of the id attributes by matching them and doing nothing else. Output. xml< productsauthor="Jesper"> В В < product> В В В В < name> Delta< /name> В В В В < price> 8. В В В В < stock> 4< /stock> В В В В < country> Denmark< /country> В В < /product> < !- - etc - -> < /products> 6. Not some elements. Stylesheet. xslt< xsl: templatematch="@*|node()"> В В < xsl: copy> В В В В < xsl: apply- templatesselect="@*|node()"/> В В < /xsl: copy> < /xsl: template> < xsl: templatematch="country"/> The first template matches all attributes and all nodes being children of other nodes, and copies them over. The second template matches the country elements of the context element and cancels the copying of those elements by doing nothing else. The first template puts node after node in context making it possible for the second template to match the country elements. Output. xml< productsauthor="Jesper"> В В < productid="p. В В В В < name> Delta< /name> В В В В < price> 8. В В В В < stock> 4< /stock> В В < /product> < !- - etc - -> < /products> 7. Not comment nodes. In this case we could have excluded them in the first place but it is nice always to use match="@*|node()" making it easy to transfer the identity template to a separate template library we can include in stylesheets. Stylesheet. xslt< xsl: templatematch="@*|node()"> В В < xsl: copy> В В В В < xsl: apply- templatesselect="@*|node()"/> В В < /xsl: copy> < /xsl: template> < xsl: templatematch="comment()"/> The first template matches all attributes and all nodes being children of other nodes, and copies them over. The second template matches the comment nodes being children of the context node element and cancels the copying of the comment nodes. Output. xml< productsauthor="Jesper"> < !- - etc - -> В В < productid="p. В В В В < name> Foxtrot< /name> В В В В < price> 1. В В В В < stock> 5< /stock> В В В В < country> Australia< /country> В В < /product> В В < productid="p. В В В В < name> Tango< /name> В В В В < price> 1. В В В В < stock> 3< /stock> В В В В < country> Japan< /country> В В < /product> < !- - etc - -> < /products> Notice that the comment node between product 4 and 5, < !- - p. The two < !- - etc - -> is only used to indicate that not all the products are shown. Rename an attribute. Stylesheet. xslt< xsl: templatematch="@*|node()"> В В < xsl: copy> В В В В < xsl: apply- templatesselect="@*|node()"/> В В < /xsl: copy> < /xsl: template> < xsl: templatematch="@id"> В В < xsl: attributename="p. Id" select="."/> [4]< /xsl: template> The first template matches all attributes and all nodes being children of other nodes, and copies them over. The second template matches the "id" attribute of the context element. The first template puts node after node in context making it possible for the second template to find the "id" attributes. The second template cancels the copying of the "id" attributes by creating a new attribute named "p. Id". The context, ".", the value of the canceled "id" attribute, is copied over. Output. xml< productsauthor="Jesper"> В В < productp. Id="p. 1"> В В В В < name> Delta< /name> В В В В < price> 8. В В В В < stock> 4< /stock> В В В В < country> Denmark< /country> В В < /product> < !- - etc - -> < /products> 9. Rename an element. Stylesheet. xslt< xsl: templatematch="@*|node()"> В В < xsl: copy> В В В В < xsl: apply- templatesselect="@*|node()"/> В В < /xsl: copy> < /xsl: template> < xsl: templatematch="products"> В В < catalog> В В В В < xsl: apply- templatesselect="@*|node()"/> В В < /catalog> < /xsl: template> The first template matches all attributes and all nodes being children of other nodes, and copies them over. The second template matches the "products" element and cancels the copying. Products" is renamed to "catalog" and the copying is restarted. We could have used < xsl: element name="catalog"/> instead of < catalog/>. Output. xml< catalog> В В < productid="p. В В В В < name> Delta< /name> В В В В < price> 8. В В В В < stock> 4< /stock> В В В В < country> Denmark< /country> В В < /product> < !- - etc - -> < /catalog> 1. Add a new attribute. Stylesheet. xslt< xsl: templatematch="@*|node()"> В В < xsl: copy> В В В В < xsl: apply- templatesselect="@*|node()"/> В В < /xsl: copy> < /xsl: template> < xsl: templatematch="products"> В В < xsl: copy> В В В В < xsl: attributename="date. Updated"> В В В В В В < xsl: value- ofselect="current- date. Time()"/> В В В В < /xsl: attribute> В В В В < xsl: apply- templatesselect="@*|node()"/> В В < /xsl: copy> < /xsl: template> In the second template we cancel the copying of the products element. After having created the new attribute we "restart" the copying. Please note that the current- date. Time() function is new in XPath 2. Output. xml< productsdate.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. Archives
September 2016
Categories |