Building Oracle XML Applications phần 8 pps

89 283 0
Building Oracle XML Applications phần 8 pps

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

15.1.3.2 Setting HTTP session variables When using XSQL Pages with the XSQL Servlet, you can refer to variables set in the HTTP session. These are variables whose values persist for a single user's session with your web server. If you have not otherwise created the HTTP session, then it is created the first time an <xsql:set-session-param> action is encountered. The HTTP session and the variables within it stay alive for a period of time specified by your servlet engine configuration. To set the value of an HTTP session-level variable, use the syntax: <xsql:set-session-param name="pname" value="val"/> As with any action element attribute, the value="val" attribute can reference other parameters or be a static value. You can also assign the session-level variable a value retrieved from the database using the syntax: <xsql:set-session-param name="pname"> <! Select statement returning one row and one column here > SELECT Statement </xsql:set-session-param> For example, the following syntax sets the value of the session-level shopper-id parameter to the next value from a database sequence: <! Set the value of a session-level param to value from the database > <xsql:set-session-param name="shopper-id"> SELECT shopper_id.nextval FROM DUAL </xsql:set-session-param> Usually, you want to set a session-level variable only once during the current session. You can ensure that this happens by including the additional only-if-unset="yes" attribute on the action element, like this: <! | Set the value of a session-level param to value from the database | Only set it if the value has never been set before in this session. + > <xsql:set-session-param name="shopper-id" only-if-unset="yes"> SELECT shopper_id.nextval FROM DUAL </xsql:set-session-param> In addition, you may not want to set the value of the session variable at all if the value to which it is being assigned is a blank or null value. To prevent a session variable from having its value assigned to an empty string, add the ignore-empty-value="yes" attribute on the action element, like this: <! | Set the value of the session level variable to 'Yes' if a row is | returned from the query. If no row is returned (producing a NULL value | to be set) do not set the parameter value. + > <xsql:set-session-param name="existing-customer" ignore-empty-value="yes"> SELECT 'Yes' FROM customer_table WHERE customer_id = {@custid} </xsql:set-session-param> The same technique applies to the case when the value is set using the value="val" syntax: <! | Remember the value of the most recently selected menu choice | in a session level parameter. Only set the value of "last-menu-choice" | to a new value if the "choice" parameter has a non-empty value. + > <xsql:set-session-param name="last-menu-choice" value="{@choice}" ignore-empty-value="yes"/> You can combine only-if-unset="yes" and ignore-empty-value="yes" to achieve both effects if desired. As we've seen, session-level variables can be good for remembering values across page requests that are specific to a given user's current session. Note that JavaServer pages or servlets can set session variables programmatically that are visible to your XSQL pages, and your XSQL pages can set session-level variables that can be read by JSPs or servlets executed by the same browser user in the current session. 15.1.3.3 Setting HTTP cookie values You can store parameter values across user sessions using HTTP cookies. The <xsql:set-cookie> action enables your XSQL pages to set the name and value of the cookie, as well as several parameters that govern its lifetime and visibility. The basic syntax is: <xsql:set-cookie name="pname"> <! Select statement returning one row and one column here > SELECT Statement </xsql:set-cookie> or: <xsql:set-cookie name="pname" value="val"/> The following additional attributes can be used on an <xsql:set-cookie> element: max-age ="numsecs" Indicates that the cookie value will expire after numsecs seconds. If no number is specified, the cookie will expire when the user exits the current browser instance. domain ="servername" Indicates that the cookie value will be readable in the servername domain. If no server is specified, the cookie will be readable in the full domain name of the current XSQL page being requested. path ="pathname" Indicates that the cookie value will be readable only for URLs in the pathname path relative to the cookie's domain or in subdirectories. If no path is specified, the cookie will be readable in the URL path of the current XSQL page being requested. The ignore-empty-value="yes" and only-if-unset="yes" attributes may also be used, and will behave the same as for session-level parameters. For example, assume that a user has submitted an HTML login form complete with username and password. You can look up this username/password combination in your registered_users table and set the value of a cookie named siteuser if the combination matches. The following XSQL page would handle this: <page connection="xmlbook" xmlns:xsql="urn:oracle-xsql"> <! | If the username/password combo matches, | set a siteuser cookie that will expire in | 1 year (= 365 days * 24 hours * 60 min * 60 sec) + > <xsql:set-cookie name="siteuser" max-age="31536000" only-if-unset="yes" ignore-empty-value="yes"> SELECT username FROM site_users WHERE username = '{@username}' AND password = '{@password}' </xsql:set-cookie> <! Other Actions Here > </page> Because they are HTTP-specific, session-level parameters and cookies are useful only in XSQL pages that will be requested through the XSQL Servlet over HTTP. If you use the XSQL command-line utility or the XSQLRequest class to process an XSQL page containing <xsql:set-session-param> and/or <xsql:set-cookie> actions, session-level parameters and cookies will have no effect. 15.1.3.4 Setting XSLT stylesheet parameters XSLT stylesheets can be parameterized by declaring top-level stylesheet parameters. An example of a stylesheet that declares such a parameter is shown here: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <! XSLT stylesheet parameter "imageDir", overridable default value provided > <xsl:param name="imageDir">/images</xsl:param> <! XSLT stylesheet parameter "Theme", overridable default value provided > <xsl:param name="Theme">default.css</xsl:param> <xsl:template match="/"> <! etc. > </xsl:template> </xsl:stylesheet> Using the <xsql:set-stylesheet-param> action, an XSQL page can assign values to these stylesheet parameters. Following the examples above, the syntax is either: <xsql:set-stylesheet-param name="pname"> <! Select statement returning one row and one column here > SELECT Statement </xsql:set-stylesheet-param> or: <xsql:set-stylesheet-param name="pname" value="val"/> For example, the following XSQL page sets the values of the imageDir and Theme stylesheet parameters: <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="SomeSheet.xsl"?> <page connection="xmlbook" xmlns:xsql="urn:oracle-xsql"> <! Set the stylesheet parameter named imageDir > <xsql:set-stylesheet-param name="imageDir" value="{@subdir}/graphics"/> <! Set the stylesheet param named Theme by retrieving a user preference > <xsql:set-stylesheet-param name="Theme"> SELECT selected_theme FROM user_prefs WHERE userid = {@currentuser} </xsql:set-stylesheet-param> <! Other actions here > </page> If you find yourself using <xsql:set-stylesheet-param> to set many stylesheet parameters to the value of XSQL page parameters, you might consider using <xsql:include-request-params>, described later, which includes all request parameters, session variables, and cookies into your XSQL data page in a single action. Once they are part of your data page, they are accessible in the stylesheet via XPath expressions. 15.1.4 Supported Sources of XML Content In addition to the static XML elements in your XSQL page and the dynamically produced XML content resulting from the <xsql:query> action elements, you can exploit several additional options for assembling interesting XML information into your XSQL data page before delivering it or transforming it using XSLT. 15.1.4.1 Including parameter values To include the value of any parameter pname into your XSQL data page, use the <xsql:include-param> action. It takes a single name attribute indicating the name of the parameter to include: <xsql:include-param name="pname"/> The <xsql:include-param> element is replaced by an element with the same name as the parameter having the parameter value as its text content. Therefore, an action like: <xsql:include-param name="sku"/> produces the element: <sku>1234567</sku> Note that it is possible to use this in combination with <xsql:set-page-param> to retrieve a value from the database as a page-level parameter and then insert it into the database. For example: <! Retrieve name of sales rep for customer whose id is passed in 'cust' parameter > <xsql:set-page-param name="salesRepName"> SELECT rep_name FROM customer_sales_rep WHERE custid = {@cust} </xsl:set-page-param> <! Insert salesRepName param into the data page > <xsql:include-param name="salesRepName"/> produces the XML element: <salesRepName>Jimmy</salesRepName> However, it is more convenient to use <xsql:query> directly, in combination with SQL column aliasing and suppressing rowset-element and row-element: <! Insert salesRepName for customer whose id is passed in 'cust' parameter > <xsql:query rowset-element="" row-element=""> SELECT rep_name AS "salesRepName" FROM customer_sales_rep WHERE custid = {@cust} </xsql:query> which produces the equivalent single element: <salesRepName>Jimmy</salesRepName> This technique is preferable for including "singleton" database lookup values because it can easily be leveraged to use a single SELECT statement to retrieve multiple lookup values in a single database round-trip. For example, if you need to retrieve not only a sales representative's name, but also the rep's phone number and fax number, you can extend the previous example to look like this: <! Insert salesRepName for customer whose id is passed in 'cust' parameter > <xsql:query rowset-element="" row-element=""> SELECT rep_name AS "salesRepName", rep_phone AS "phoneNumber", rep_fax AS "faxNumber" FROM customer_sales_rep WHERE custid = {@cust} </xsql:query> and, with a single SQL statement, you add these three elements to the page: <salesRepName>Jimmy</salesRepName> <phoneNumber>677-899-1001</phoneNumber> <faxNumber>677-899-1002</faxNumber> If, instead, you used the combination of <xsql:set-page-param> and <xsql:include-param> you would need three queries to achieve the same effect, since each <xsql:set-page-param> assigns only the value of a single parameter from the first column of the SELECT statement. Therefore, <xsql:include-param> is most useful for including a single or a small number of request parameters in the data page. 15.1.4.2 Including all request parameters If you want to make the entire set of all request parameters, session variables, and cookies available to the XSLT stylesheet in your XSQL page, use the <xsql:include-request-params> action. The action element is replaced in the page at page-request time with a subtree of XML elements that represents all of the interesting parameters available to the request. The format of the included XML document fragment when the page is requested through the XSQL Servlet looks like this: <request> <parameters> <param1>value1</param1> <param2>value2</param2> : </parameters> <session> <name1>val1</name1> <name2>val2</name2> : </session> <cookies> <cookiename1>value1</cookiename1> : </cookies> </parameters> When you use the XSQL command-line utility or the XSQLRequest class, the <session> and <cookies> sections are not relevant, so they are not present. The included document fragment in these cases will look like this: <request> <parameters> <param1>value1</param1> <param2>value2</param2> : </parameters> </parameters> In contrast with the <xsql:include-param>, this technique makes it possible to distinguish whether a parameter is a request parameter, session parameter, or cookie because its value will appear as an element in a child of request/parameters, request/session, or request/cookies, respectively. Using <xsql:include-param>, only the value of the parameter is included; and it is not possible to infer whether the value was a request, session, or cookie-based value. For example, in the following XSQL page: <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="SomeSheet.xsl"?> <page connection="xmlbook" xmlns:xsql="urn:oracle-xsql"> <! Include all request parameters in the data page > <xsql:include-request-params/> <! Other actions here > </page> the associated SomeSheet.xsl stylesheet can contain conditional logic to format the page differently if the user is logged in, based on the presence of an HTTP cookie named forumuser. A fragment of such a stylesheet would look like this: <! If the user is logged in, say hello. Otherwise show login link > <xsl:choose> <xsl:when test="/page/request/cookies/forumuser"> <b>Hello, <xsl:value-of select="/page/request/cookies/forumuser"/></b> </xsl:when> <xsl:otherwise> <a href="Login.xsql">Login</a> </xsl:otherwise> </xsl:choose> Using <xsql:include-request-params>, the stylesheet can tell the difference between a forumuser cookie that it set and a forumuser request parameter that a clever user might pass as part of the URL. 15.1.4.3 Including encapsulated, dynamic queries When delivering data that must be highly customized by users, or when trying to support an arbitrary query by example on many optional query parameters, even the most clever use of XSQL parameter substitution in your <xsql:query>'s SELECT statement is often not right for the job. In these cases, when the structure of the query itself must change dynamically, it is possible to handle the job quite easily by using the <xsql:ref-cursor-function> action instead of <xsql:query>. As the name implies, <xsql:ref-cursor-function> allows you to invoke a database function that returns a reference to a dynamically created cursor and automatically include an XML representation of its query results in your data page. Leveraging Oracle8i 's native dynamic SQL feature, your database stored function can literally create any valid SELECT statement in a string, based on any number of decisions your code needs to make, and return a cursor over the query results on that query to your XSQL page. All of the optional attributes supported on the <xsql:query> action element with the exception of fetch-size are also supported on the <xsql:ref-cursor-function> so you have the same degree of control with total flexibility as to the nature of the query being performed. To return a dynamic query result, your database stored function must exist in a package that declares a weakly typed REF CURSOR type in the package specification to use as the function return value, like this: [...]... the XSQL page: when requested with the URL: http://server/include -xml- example.xsql?tla =XML returns the XML data page shown... create the simple XSQL page: DeptOrEmp.getInfo({@id}) When this page is invoked with the URL: http://xmlapps/enpdept.ssgl?id= 783 9 we get: 783 9 KING PRESIDENT 11/17/1 981 0:0:0 5000 10 ... of the XML messages from the table by message ID, like this: < ?xml version="1.0"?> < ?xml- stylesheet type="text/xsl" href="Message.xsl"?> SELECT message as "Message" FROM xml_ business_messages WHERE id = {@id} The Message.xsql page uses the following Message.xsl stylesheet to output the XML text... Appropriate to Requesting Browser < ?xml version="1.0"?> < ?xml- stylesheet type="text/xsl" media="msie 5.0" client="yes" < ?xml- stylesheet type="text/xsl" media="lynx" href="SiteMenu-lynx.xsl"?> the < ?xml- stylesheet type="text/xsl" href="SiteMenu.xsl"?> SELECT name, icon,... as follows: SELECT sku, price, description, decode(qty,0,'Backordered','In Stock') as status FROM product WHERE sku = '{@id}' and: XML Minlaton, Sa, Australia Of course, the results of the XML resource referenced by an element must be well-formed XML; otherwise, an element will be added to your XSQL page instead of the XML you were expecting 15.1.4.5 Including dynamic XML from PL/SQL In Chapter 10,... developers can use to serve XML using the Oracle Web Agent (OWA) packages The generated XML is printed to a PL/SQL page buffer using the routines in the HTP package, and the result is pulled from that buffer and delivered to the requester over the Web by any of the following: • Oracle Internet Application Server 1.0 with modplsql • Oracle Web Application Server 3.0/4.0 Oracle Web Server 2.1 WebDB Lightweight... SYSDATE+(1/24) Then you can reuse these files in your original BrowseProduct.xsql and any others that need common queries, like this: < ?xml version="1.0"?> < ?xml- stylesheet type="text/xsl" href="BrowseProduct.xsl"?> Notice that when the ... retrieves product information for the current product being browsed, along with a list of active promotions going on this hour like this: < ?xml version="1.0"?> < ?xml- stylesheet type="text/xsl" href="BrowseProduct.xsl"?> SELECT sku, price, description, decode(qty,0,'Backordered','In Stock') as status... itself to introduce < ?xml- stylesheet?> instructions You simply build one or more new XSQL pages that look like this: < ?xml version="1.0"?> < ?xml- stylesheet type="text/xsl" href="SomeNewTransformation.xsl"?> Now that . < ?xml version="1.0"?> < ?xml- stylesheet type="text/xsl" href="SomeSheet.xsl"?> <page connection="xmlbook" xmlns:xsql="urn :oracle- xsql">. < ?xml version="1.0"?> < ?xml- stylesheet type="text/xsl" href="SomeSheet.xsl"?> <page connection="xmlbook" xmlns:xsql="urn :oracle- xsql">. connection="xmlbook" xmlns:xsql="urn :oracle- xsql"> DeptOrEmp.getInfo({@id}) </xsql:ref-cursor-function> When this page is invoked with the URL: http://xmlapps/enpdept.ssgl?id= 783 9

Ngày đăng: 08/08/2014, 18:21

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan