Return-Path: Delivered-To: apmail-cocoon-docs-archive@www.apache.org Received: (qmail 32901 invoked from network); 12 Nov 2004 17:04:23 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 12 Nov 2004 17:04:23 -0000 Received: (qmail 78420 invoked by uid 500); 12 Nov 2004 17:04:22 -0000 Delivered-To: apmail-cocoon-docs-archive@cocoon.apache.org Received: (qmail 78397 invoked by uid 500); 12 Nov 2004 17:04:21 -0000 Mailing-List: contact docs-help@cocoon.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: list-post: Reply-To: docs@cocoon.apache.org Delivered-To: mailing list docs@cocoon.apache.org Received: (qmail 78384 invoked by uid 99); 12 Nov 2004 17:04:21 -0000 X-ASF-Spam-Status: No, hits=-10.0 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME,WEIRD_PORT X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Fri, 12 Nov 2004 09:04:17 -0800 Received: (qmail 32848 invoked from network); 12 Nov 2004 17:04:16 -0000 Received: from localhost.hyperreal.org (HELO minotaur.apache.org) (127.0.0.1) by localhost.hyperreal.org with SMTP; 12 Nov 2004 17:04:16 -0000 Content-Type: text/plain; charset="iso-8859-1" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: docs@cocoon.apache.org To: docs@cocoon.apache.org Subject: =?iso-8859-1?q?=5BCocoon_Wiki=5D_New=3A__HowToCreateHiearchicalXmlUsingES?= =?iso-8859-1?q?QL?= Date: Fri, 12 Nov 2004 17:04:16 -0000 Message-ID: <20041112170416.32831.82814@minotaur.apache.org> X-Spam-Rating: localhost.hyperreal.org 1.6.2 0/1000/N X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N Date: 2004-11-12T09:04:15 Editor: PavelVrecion Wiki: Cocoon Wiki Page: HowToCreateHiearchicalXmlUsingESQL URL: http://wiki.apache.org/cocoon/HowToCreateHiearchicalXmlUsingESQL new how to document New Page: =3D How to create hiearchical xml using ESQL =3D This How-To describes the steps to write xsp that produces XML hierarchical= structure using ESQL nested queries.[[BR]] Autor: '''Pavel Vrecion''' =3D Purpose =3D There is quite often need to create master-detail web pages based on databa= se queries.[[BR]] Typical example is company that has more departments with employees.[[BR]] In this case we would like to create XML structure starting with company, w= ith more child elements describing department and on next level also child = elements for each employee. Note that for such tasks Cocoon has already par= tial support in ESQL called group queries, but this is limited to two level= queries. We will examine the other way, how to achieve this. = It will enable us to create richer XML structures.[[BR]] During the process we will also learn how to interweave Java and SQL. ---- =3D Prerequisites =3D We will need Cocoon (of course) and database with at least two tables linke= d by =93one to many=94 reference.[[BR]] In the example we will use Firebird database engine and we will utilize exa= mple databases employee.fdb, which is included in Firebird installation. But other databases with JDBC support will work, too.[[BR]] Consult Cocoon and/or JDBC and your database documentations for details reg= arding database installation, running, parameters and JDBC connections. =3D Steps briefly =3D We will:[[BR]] 1. create at least two tables (or you can skip this step and use already ex= isting database)[[BR]] 2. define database connection pool in cocoon.xconf (Cocoon main configurati= on file)[[BR]] 3. create application with:[[BR]] - simple sitemap[[BR]] - and simple xsp (XML Server Page)[[BR]] 4. create simple stylesheet to transform XML into HTML =3D Steps in detail =3D =3D=3D Database tables =3D=3D We will need two tables, one for department and second for employee.[[BR]] Two tables will be linked through =93one to many=94 relationship.[[BR]] Employee table will have department foreign key =96 department id, which wi= ll link employee to department.[[BR]] [[BR]] You can create tables with following SQL DDL statements:[[BR]] {{{ CREATE TABLE DEPARTMENT ( DEPT_NO CHAR(3) NOT NULL, DEPARTMENT VARCHAR(25) NOT NULL, HEAD_DEPT CHAR(3), LOCATION VARCHAR(15), PHONE_NO VARCHAR(30) }}} {{{ CREATE TABLE EMPLOYEE ( EMP_NO INTEGER, FIRST_NAME VARCHAR(30), LAST_NAME VARCHAR(40), PHONE_EXT VARCHAR(4), DEPT_NO CHAR(3), JOB_CODE VARCHAR(4), JOB_COUNTRY VARCHAR(15) }}} Well, if you like, you can also create some integrity constraints and other= fancy database stuff like sequences, triggers, = but for our purpose SQL, we have mentioned above, is fine.[[BR]] Note that column {{{DEPT_NO}}} is primary key in {{{DEPARTMENT}}} table (an= d so should have mandatory and unique value). = Same column and its value is used in {{{EMPLOYEE}}} table to link specific = employee to specific department. = HEAD_DEPT is =93self reference=94 and can be used to create rich company st= ructure that consists from divisions, departments, sub-departments etc.[[BR= ]] To verify that everything works you should test database using some SQL too= l. = It is good idea to add some test, but meaningful, data during the process, = too.[[BR]] When we have tables in the database we must tell Cocoon, where to find the = data and how to connect to database. = That is why we will add new datasource to Cocoon configuration file. =3D=3D Adding new datasource to cocoon.xconf =3D=3D Find {{{cocoon.xconf}}} (usually located in Cocoon directory {{{build/webap= p/WEB-INF}}}), open it with some text editor, = find datasources section and add new connection parameters. = After editing datasource part of {{{cocoon.xconf}} it will look somehow lik= e this: {{{ .... = true jdbc:firebirdsql:localhost/3050:c:\PathToDB\EMPLOYEE.FDB = MyName MyPassword = ..... }}} We suppose that you have already downloaded and installed database engine a= nd libraries, = and you have added JDBC driver name to Cocoon {{{web.xml}}} configuration f= ile (located in the same directory as {{{cocoon.xconf}}}).[[BR]] Your {{{web.xml}}} should have param-value element under servlet/init-param= elements similar to this: {{{ load-class org.hsqldb.jdbcDriver = org.firebirdsql.jdbc.FBDriver com.mysql.jdbc.Driver }}} Note that in this example there are specified drivers for several database = engines. = If you use some other database, please consult corresponding documentation.= [[BR]] After these steps we should have database and Cocoon up and running, Cocoon= also should already =93know=94 how to connect to database.[[BR]] We are ready to start writing xsp and ultimately to show some data to crowd= of cheering users. =3D=3D Writing XSP =3D=3D As you remember, main purpose of our xsp is to present data from database i= n rich xml structure. = We will do it by executing SQL SELECT command that will return rowset of de= partments. [[BR]] We will save department id (identification, or primary key) into Java varia= ble and use it in nested query. [[BR]] Nested query will then produce list of employees for each department.[[BR]] Clear? No? Don=92t worry, and let=92s go to examples. [[BR]] Create new directory called test (for example) in Cocoon {{{build/webapp}}}= directory (other applications are located there, too) and create new text = file named empxml.xsp (you can name it differently, of course). Add followi= ng code to it and save it.[[BR]] {{{ int deptno=3D-1; dbCompany = select DEPT_NO, DEPARTMENT, LOCATION, PHONE_NO from DEPARTME= NT deptno=3D; = select FIRST_NAME, LAST_NAME, PHONE_EXT, JOB_CODE, JOB_COUNTRY from EMPLOYEE where DEPT_NO =3D deptno order by LAST_NAME, FIRST_NAME = = = = }}} OK we have xsp page. Note that we have filled Java variable '''with''' ESQL= command[[BR]] {{{deptno=3D; }}} And then used Java variable '''in''' ESQL command {{{ select FIRST_NAME, LAST_NAME, PHONE_EXT, JOB_CODE, JOB_COUNTRY from EMPLOYEE where DEPT_NO =3D deptno order by LAST_NAME, FIRST_NAME }}} That is the main trick of nested queries and hierarchical structures.[[BR]] As a next step we will create simple sitemap in our application directory. =3D=3D Simple sitemap =3D=3D Sitemap will be really simple. = Its only purpose is to show one page, we have just created. = Create new text file called sitemap.xmap in application directory and fill = it with following text: {{{ }}} At this stage we should have 2 files in our example application directory: * {{{empxml.xsp}}} * {{{sitemap.xmap}}}[[BR]] We have created xsp that produces xml structure. We have also sitemap with = pipeline that calls this xsp when Cocoon gets employee.xml request. [[BR]] So let=92s try it. In your favorite browser type url (when you run Cocoon l= ocally, your url will probably be {{{http://localhost:8888/test/employees.x= ml}}}).[[BR]] You should see xsp result in the structured XML form, something like this: {{{ Corporate Headquarters Monterey (408) 555-1234 Sales and Marketing San Francisco (415) 555-1234 MacDonald Mary S. VP USA 477 Yanowski Michael SRep USA 492 Engineering ...... }}} Note that department can be linked to parent department through HEAD_DEPT c= olumn. So, as homework, you can enhance example application by modifying xs= p so that it will contain nested queries: {{{ select * from DEPARTMENT where HEAD_DEPT is null -- (get company divisions) select * from EMPLOYEE where DEPT_NO =3D deptno -- (ge= t division employees) select * from DEPARTMENT where HEAD_DEPT =3D deptno --= (get divisions departments i.e. second level departments) select * from EMPLOYEE where DEPT_NO =3D deptno -- (ge= t department employees) }}} =85 and so on for other levels. In this case resulting XML will have more l= evels because DEPARTMENT elements will have child DEPARTMENT elements (you = can also use DIVISION - DEPARTMENT, or other tag names according to your n= eeds or taste).[[BR]] You should see xml, maybe even in the structure, you have expected. You are= happy, but your users expect some fancy graphics with company logo, and th= ey strictly demand yellow text on pink background.[[BR]] Well, make them happy, too. We will write xsl and postpone our celebration,= but just a little.[[BR]] XSL has one hidden virtue, it divides data and presentation. And we just kn= ow, that our users will strictly demand something else next week, and quite= often they will act in separated groups divided by languages, browsers etc= . This approach opens the way how to serve them all, and how to make later = changes fast.[[BR]] =3D=3D Simple XSL =3D=3D To keep things simple and clear, we will start with several HTML lines for = each department and one table for department employees.[[BR]] Create new file {{{employees.xsl}}} in application directory and fill it wi= th following content: {{{ = My company departments

Location:
Phone:

Department employees
Employee Job code Job country Phone extension

}}} Now we will use this xslt code to transform xml data into html. = To do it, we must enhance Cocoon application sitemap a little. = Add several lines to {{{sitemap.xmap}}}, so the new sitemap will look like = this:[[BR]] {{{ }}} At this stage we should have 3 files in our example application directory: * {{{empxml.xsp}}} (producing xml from database) * {{{sitemap.xmap}}} (describing our application components and basic flow= of pages) * {{{employees.xsl}}} (transforming xml into html) After calling {{{employees.html}}} (for example {{{http://localhost:8888/te= st/employees.html}}} we should see html formatted text: [[BR]][[BR]] '''Corporate Headquarters'''[[BR]] Location: Monterey[[BR]] Phone: (408) 555-1234 ||||||||Department employees|| ||Employee||Job code||Job country||Phone extension|| [[BR]] '''Sales and Marketing'''[[BR]] Location: San Francisco[[BR]] Phone: (415) 555-1234 ||||||||Department employees|| ||Employee||Job code||Job country||Phone extension|| ||Warvick Mary S.||VP||USA||477|| ||Yanowski Michael||SRep||USA||492|| [[BR]] '''Engineering'''[[BR]] Location: Monterey[[BR]] Phone: (408) 555-1234 ||||||||Department employees|| ||Employee||Job code||Job country||Phone extension|| ||Brown Kelly||Admin||USA||202|| ||Nelson Robert||VP||USA||250|| [[BR]]....[[BR]] In praxis you will probably spend some more time playing with HTML layout, = fonts, colors and graphics, but believe me, = better is to find somebody who really has the taste, and who will do HTML c= oding in xsl much better then we, programmers, usually do. =3D Achievements =3D We have learned how to use xsp and how to mix Java and SQL codes to create = hierarchical structures.[[BR]] Such approach has several advantages. Code is short and more readable.[[BR]] Hierarchical XML structure simplifies transformations like using XSLT for H= TML pages, as well as any other automated processing. = And, as a bonus, data, logic and presentation layers are kept apart. =3D Comments =3D Care to comment on this How-To? [[BR]] Got another tip? [[BR]] Help keep this How-To relevant by passing along any useful feedback to the = author, [mailto:pavel.vrecion@plarmy.org Pavel Vrecion.]