Object-oriented XSLT Programming

Source: Internet
Author: User
Tags xslt


Now
In, many applicationsProgramUse XML
And the data may be distributed in different places. In actual use, XML data of these distributions must be expressed in different views. The style sheet provides business data and representation.
The Separation Method of layer, as a tool for XML data conversion, can be expressed through XML data. A style sheet can present distributed XML data in a certain view.
The problem is how to generate multiple style sheets acting on distributed XML data to generate different views. This section describes how to assemble XSLT Based on the style sheet component. Its core is to use the OO idea to construct
Create a series of XSLT template files (XSLT document components), use an XSLT assembler to dynamically assemble a complete XSLT document based on customer requests, and apply it to distributed
XML document. Thus, different users are provided with different presentation layers.

Overview of sample applications

To demonstrate object-oriented XSLT programming, I will take the product directory system as an example. In the product directory system, different users can obtain different presentation layers. In this example, we assume three users:
General users, Senior users and internal users. Different users have different presentation views. For example, the discount rates of users of different levels are different, which leads to different retail prices, while internal users may need to obtain product suppliers.
. Product Information, supplier information, and discount rate information are stored in different XML documents. List 1 is the product list, list 2 is the supplier information, and list 3 is
Discount Rate information. The system dynamically generates a style sheet based on the user's category. The principle of the system is to first generate multiple XSLT document components, each of which is responsible for part of the Conversion Function, just like the various
Class. At the same time, we will generate an XSLT document assembler. Its core is actually an XSLT document, but it can receive the parameters passed to it by the application and group multiple XSLT documents according to the parameters.
Complete XSLT document.

Design of style sheet Components

XSLT is actually composed of a series of matching templates, naming templates, and a set of attributes, parameters, and variables. When it acts on an XML data source, you can perform some operations according to the defined template. To some extent
The visual style sheet is a class in OO. Therefore, some oo ideas can be introduced into the design of style sheets. The following introduces the OO concept that can be introduced in the design of the style sheet component.

Basic style table Component Design

First, we designed the basic style sheet components. According to the requirements of the system, we designed three basic style sheets: Product Style Sheets, supplier style sheets, and discount rate style sheets. List 4 is
A product style sheet is the main style sheet of the entire product catalog system. Later, the style sheet will be extended based on it. It is like the base class of the system. The supplier style sheet function is used to convert supplier information because
The required information is in different XML documents, while the system's main style sheet is the product style sheet, and the product list XML document is the main source document. Therefore, the supplier XML document used by the supplier style sheet as the auxiliary source
Document, which must be loaded by document. Listing 1 shows how to use the document function to obtain the required node set. List 5 is a complete supplier style sheetSource code.

Listing 1


<XSL: Template Name = "supliershow">
<XSL: Param name = "Sid"/>
<XSL: variable name = "supplier" select = "document ('suppliers. xml',.) // supplier [@ ID = $ Sid]"/>
......
</XSL: Template>

The discount rate style table is used to determine the retail price of a product based on the user's level. Like the supplier style sheet, it also needs to obtain the discount rate information from the discount rate XML document and calculate the price based on the user level. Listing 2 shows how to calculate the retail price. LIST 6 is the complete source of discount rate stylesCode.

Listing 2


<XSL: Template Name = "discount">
<XSL: Param name = "catalog"/>
<XSL: Param name = "price"/>
<XSL: Param name = "customertype"/>
<XSL: variable name = "discountprice">
<XSL: Choose>
<XSL: When test = "$ customertype = 'normal user'">
<XSL: variable name = "discountrate"
Select = "document ('discounts. xml',.) // general user/discount [@ Category = $ catalog]/@ discount rate"/>
<XSL: value-of select = "$ price * $ discountrate"/>
</XSL: When>
......
</XSL: Template>

Now, we have designed the basic components of the style sheet. The concept of OO is introduced to the design of the style sheet.

Inheritance in style sheets

There are two ways to reuse style sheets in XSLT: import and include ). The difference between the two methods is: include simply adding a style sheet to the main style sheet
Contains their locations. The contained style sheet is inserted into the main document, as if the contained file is directly read from the data stream. The difference between import and include is that only the call document does not have the same life cycle.
The import template is used only when the name parameter or template is used. Although the inclusion method is fast in compilation, it cannot explicitly reload the template. Therefore, in this example, the import method is used. In this example, the internal user's product style sheet is
The Product Style Sheet extends the supplier information. An internal user's Product Style Sheet inherits the main product style sheet and extends its own functions. Listing 3 shows how to extend the style sheet by using the import mechanism. List 7 is the complete source code of the style sheet of the internal user product, which is generated by the XSLT document assembler.

Listing 3


<XSL: stylesheet xmlns: XSL = "http://www.w3.org/1999/XSL/Transform" version = "1.0">
<! -- Import a style sheet -->
<XSL: Import href = "supplier. XSLT"/>
......
<! -- Display the overload template -->
<XSL: template match = "supplier">
<XSL: Apply-imports/>
</XSL: Template>
</XSL: stylesheet>

Reload in the style sheet

The <XSL: Template> and <XSL: Apply-Temples> command elements in the style sheet have the mode attribute.
The <XSL: Apply-Temples> element with the mode attribute looks for a <XSL: Template> element with the same mode
And process the template content, ignoring the template rules that do not match the pattern. Using the pattern attribute of the template, we can define multiple templates for the same XML document element, and then determine
Determine which template to call. Listing 4 shows how to use mode attributes. Similarly, the <XSL: Apply-imports> command element can also be used for style sheet overloading.
The template in the imported style sheet has a lower priority than the same template in the imported style sheet. Even the imported template has a higher priority attribute (priority) than the original template in the style sheet) this is also true.
The <XSL: Apply-imports> element has similar functions similar to the super () method in OOP. It can notify the XSLT processing program in the imported document
Use the import template. In addition, the called import template must match the current environment node. Listing 5 shows how to use the import template. One problem in listing 5 is that the imported Template
(Discount. XSLT) has the mode attribute, but the main template does not have the mode attribute. Therefore, the corresponding matching template cannot be correctly imported in the main template. Therefore, we need to use XSLT
File assembler to add the corresponding mode attribute to the main template. This issue will be resolved in the next section.

Listing 4


<XSL: template match = "price" mode = "normal">
<Br/>
Discount price:
<XSL: Call-Template Name = "discount">
<XSL: With-Param name = "catalog" select = "../category"/>
<XSL: With-Param name = "price" select = "."/>
<XSL: With-Param name = "customertype" select = "'normal user'"/>
</XSL: Call-template>
</XSL: Template>
<! -- A template with the pattern attribute. It works with the <apply-templates> pattern attribute. -->
<XSL: template match = "price" mode = "advanced">
<Br/>
Discount price:
<XSL: Call-Template Name = "discount">
<XSL: With-Param name = "catalog" select = "../category"/>
<XSL: With-Param name = "price" select = "."/>
<XSL: With-Param name = "customertype" select = "'advanced user'"/>
</XSL: Call-template>
</XSL: Template>

Listing 5


<XSL: stylesheet version = "1.0" xmlns: XSL = "http://www.w3.org/1999/XSL/Transform">
<! -- Imported style table component -->
<XSL: Import href = "discount. XSLT"/>
......
<! -- Original Price matching template -->
<XSL: template match = "price">
<Br/>
Price: <XSL: value-of select = "."/>
<! -- Imported price matching template -->
<XSL: Apply-imports/>
</XSL: Template>
</XSL: stylesheet>

Implementation of XSLT document Assembler

The XSLT document assembler is actually a style sheet that assembles different style sheets as required. The oo idea mentioned in the XSLT component design is dynamically generated by the document assembler. Document Group
The idea of adding a style sheet is to extend the system's main style sheet (product list style sheet) through the style sheet import according to the customer's request. At the same time, modify the main style sheet to meet customers' requirements. Listing 6
Shows how to assemble a style sheet based on the request parameters.

Listing 6


<XSL: Param name = "customertype"/>
<! -- Input Request Parameters -->
<XSL: template match = "XSL: stylesheet">
<XSL: Copy>
<XSL: Apply-templates select = "@ *"/>
<XSL: Choose>
<! -Correctly import the style sheet component based on the Request Parameters -->
<XSL: When test = "$ customertype = 'normal user' or $ customertype = 'advanced user'">
<XSL: element name = "XSL: Import">
<XSL: attribute name = "href">
<XSL: Text> discount. XSLT </XSL: Text>
</XSL: attribute>
</XSL: Element>
</XSL: When>
<XSL: When test = "$ customertype = 'internal user'">
<XSL: element name = "XSL: Import">
<XSL: attribute name = "href">
<XSL: Text> supplier. XSLT </XSL: Text>
</XSL: attribute>
</XSL: Element>
</XSL: When>
</XSL: Choose>
<XSL: Apply-templates select = "Node ()"/>
</XSL: Copy>
</XSL: Template>

<XSL: template match = "XSL: Template">
......
<! -- Use the imported template in the matching template -'
<XSL: If test = "$ customertype = 'internal user'">
<XSL: If test = "@ match = 'vendor '">
<XSL: element name = "XSL: Apply-Imports"/>
</XSL: If>
</XSL: If>
.......
</XSL: Template>

Listing 6 shows how to assemble the style sheet document, but as we discussed in the previous section, we must solve the pattern attribute matching problem. Listing 7 shows how to solve mode attribute matching. After the mode attribute is dynamically added to the main style sheet template, the matching template in the imported style sheet can be correctly called.

Listing 7


<XSL: template match = "XSL: Template">
<XSL: Copy>
<XSL: Apply-templates select = "@ *"/>
<! -- Adds the mode attribute based on the Request Parameters -->
<XSL: If test = "$ customertype = 'normal user' or $ customertype = 'advanced user'">
<XSL: If test = "not (@ match = '/')">
<XSL: attribute name = "Mode">
<XSL: If test = "$ customertype = 'normal user'">
<XSL: Text> normal </XSL: Text>
</XSL: If>
<XSL: If test = "$ customertype = 'advanced user'">
<XSL: Text> advanced </XSL: Text>
</XSL: If>
</XSL: attribute>
</XSL: If>
<! -- Call the matching template in the imported style sheet. Because the corresponding mode attribute is added to the template in the main style sheet, it can correctly call the corresponding template of the imported style sheet -->
<XSL: If test = "@ match = 'price'">
<XSL: element name = "XSL: Apply-Imports"/>
</XSL: If>
</XSL: If>
<XSL: If test = "$ customertype = 'internal user'">
<XSL: If test = "@ match = 'vendor '">
<XSL: element name = "XSL: Apply-Imports"/>
</XSL: If>
</XSL: If>
<XSL: Apply-templates select = "XSL: Param"/>
<XSL: Apply-templates select = "Node () [not (name () = 'xsl: param')]"/>
</XSL: Copy>
</XSL: Template>

So far, we have completed the design of the style sheet, and we have designed a simple verification system. Listing 8 is the source code of the test tool. List 7 is the complete source code of the internal user product style sheet. List 8 is the complete source code of the general user product style sheet. List 9 is the complete source code of the advanced user product style sheet. They are all generated through the XSLT document assembler.

Listing 8


Import javax. xml. Transform .*;
Import java. Io .*;
Import javax. xml. Transform. Stream .*;
Public class test {
Public static void main (string [] ARGs ){
Try {
Stringwriter Sw = new stringwriter ();
Stringwriter sw2 = new stringwriter ();
Transformerfactory TF = transformerfactory. newinstance ();
// Xsltcreator. XSLT is the style sheet assembler //
Transformer trans = TF. newtransformer (New streamsource (new file ("effectcreator. XSLT ")));
// The application passes parameters to the assembler style sheet to generate the required style sheet //
Trans. setparameter ("customertype", "normal user ");
// Product_skeleton.xml is the main style table of the system //
Trans. Transform (New streamsource (new file ("product_skeleton.xml"), new streamresult (SW ));
Transformer trans2 = TF. newtransformer (New streamsource (New stringreader (SW. tostring ())));
Trans2.transform (New streamsource (new file ("products. xml"), new streamresult (sw2 ));
Fileoutputstream fo = new fileoutputstream (new file ("test "));
System. Out. println (sw2.tostring ());
Fo. Write (SW. tostring (). getbytes ());
Fo. Close ();
} Catch (exception e ){
E. printstacktrace ();
}
}
}

Instance

The following examples are provided to illustrate the object-oriented idea in XSLT programming. The instance is a simple web-based content distribution system. It dynamically generates styles based on customer requests.
Table to provide the corresponding response page. This example simply implements the idea of object-oriented XSLT programming. The system itself has not been well optimized. Figure 1 shows the system sequence.


Figure 1 system sequence diagram

The xsltservlet class is the centralized control point of user requests and the starting point of services. The xsltcreator class is the core of the XSLT assembler. Listing 9 is the main part of the implementation of javastcreator. It dynamically calls a user request or generates a style sheet to generate the corresponding response page. Complete code can be found in List 10.

Listing 9


Public void effectcreator (httpservletrequest req, httpservletresponse resp) throws ioexception, saxexception {
Stringwriter Sw = new stringwriter ();
Stringwriter sw2 = new stringwriter ();
String usertype;
Try {
Transformerfactory TF = transformerfactory. newinstance ();
TF. seturiresolver (New uriresolver (){
Public source resolve (string href, string base ){
Stringbuffer Path = new stringbuffer (base_path );
Path. append (file. separator). append (href );
File file = new file (path. tostring ());
If (file. exists () return New streamsource (File );
Return NULL;
}
});
Transformer trans =
TF. newtransformer (New streamsource
(Locator. getcachfile ("effectcreator. XSLT ")));
Httpsession session = Req. getsession ();
If (req. getparameter ("user ")! = NULL)
Session. setattribute ("usertype", req. getparameter ("user "));
Usertype = (string) Session. getattribute ("usertype ");
Trans. setparameter ("mermertype", usertype );
Trans. Transform (New streamsource
(Locator. getcachfile ("product_skeleton.xml"), new streamresult (SW ));
Transformer trans2 =
TF. newtransformer (New streamsource
(Locator. getcachfile ("productfilter. XSLT ")));
String type = (string) Req. getparameter ("producttype ");
Trans2.setparameter ("type", type );
Trans2.transform (New streamsource
(Locator. getcachfile ("products. xml"), new streamresult (sw2 ));
Transformer trans3 =
TF. newtransformer (New streamsource (
New stringreader (SW. tostring ())));
Trans3.transform (New streamsource (New stringreader (sw2.tostring ()))
New streamresult (resp. getwriter ()));
} Catch (transformerconfigurationexception e ){
Printwriter PW = resp. getwriter ();
PW. println ("<HTML> <body> <H2> tansformer error <H2> <PRE> ");
E. printstacktrace (PW );
PW. println ("</PRE> </body> } Catch (transformerfactoryconfigurationerror e ){
...
} Catch (transformerexception e ){
...
}

}

The system entry is shown in figure 2.


Figure 2 system portal page of an instance

The system dynamically generates different pages based on user requests. Figure 3 shows the content displayed after logging on as an advanced user.


Figure 3 dynamically generated product list

Summary

This article designs multiple XSLT document components to reduce the complexity of style sheet design. At the same time, it uses the XSLT document assembler to generate complex and dynamic style sheets.

References

    • Download the source code used in this article and how to use it.
    • XSLT and XPath written by J. R. Gardner: a guid to XML Transformations
    • Find more references about XML in the developerworks XML area.

Reprinted: http://www.cnblogs.com/goodspeed/articles/4027.aspx

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.