Oracle8i Application Developer's Guide - XML Release 3 (8.1.7) Part Number A86030-01 |
Library | Service | Contents | Index

Using JDeveloper to Build Oracle XML Applications, 11 of 11

## Frequently Asked Questions (FAQs): Using JDeveloper to Build XML Applications

### Constructing an XML Document in JSP

#### Question

I am dynamically constructing an XML document in a JSP page (from the results of data returned by a PL/SQL API) using the classes generated by the Class generator (based on a DTD) and then applying a XSL stylesheet to render the transformation in HTML. I see that this works fine only for the first time, i.e when the JSP is first accessed (and internally compiled), and fails every time the same page is accessed thereafter.

The error I get is:

    "oracle.xml.parser.v2.XMLDOMException: Node doesn't belong to the current
    document"

The only way to make it work again is to compile the JSP, by just 'touching' the JSP page. Of course, this again works only once. I am using Apache JServ.

How can this be overcome? Does the 'static' code in the Java class generated for the top level node have to do anything with it?

#### Answer

It seems to me that you may have stored some "invalid" state in your JSP. And the XML Parser picks this "invalid" state, then, throws the exception you mentioned.

As far as I know, CRM does not use an HTTP session in their application. I guess this is tru in your case also. You may have used a member variable to store some "invalid" state unintentionally. Member variables are the variables declared by the following syntax:

    <%! %>

For example:

    <%! Document doc=null; %>

Many JSP users misunderstand that they need to use this syntax to declare variables. In fact, you do not need to do that. In most of cases, you do not need a member variable. Member variables are shared by all requests and are initialized only once in the lifetime of the JSP.

Most users need stack variables or method variables. These are created and initialized per request. They are declared as a form of scriptlet as shown in the following example:

    <% Document doc=null; %>

In this case, every request has its own "doc" object, and the doc object is initialized to null per request.

If you do not store an "invalid" state in session or method variables in your JSP, then there may be other reasons that cause this.

### Using XMLData From BC4J

#### Question

I am using XmlData to retrieve data from a BC4J. I Do not use XmlData from a JSP, but from a standalone java application. In the record I target, I have the value 'R & D'.

XmlData returns 'R &amp; D', which is fine for HTTP, but not for my needs. Can XmlData not escape the characters, and just return what's in the database ?

#### Answer

XmlData builds an in-memory DOM, so it must be the XML parser's serialization that's doing this. The only way I know is to do the following:

1. Write your own serializer for the DOM tree that does what you want.

2. Do an identity transform augmented with one template to write that data with disable-output-escaping="yes"

### Running XML Parser for Java in JDeveloper 3.0

#### Question

I have downloaded JDeveloper 3.0 on my laptop (Windows 95 operating system). I am trying to run a sample XML parser program (SimpleParse.java). This program imports org.w3c.dom.Document class. I have set CLASSPATH in autoexe.bat with correct directory. The program runs on DOS prompt with "java SimpleParse <filename>" command. I am trying to run the same program through JDeveloper but it gives me following error:

     "identifier org.w3c.dom.Document not found"

Am I missing something ?

#### Answer

Make sure to include the Library named:

"Oracle XML Parser 2.0"

is in your project. This library is pre-defined with JDev 3.0 and you just need to visit the Project | Properties... and look at the "Paths" tab to see your project's library list.

Click the (Add...) button and pick the above library from the list.

The org.w3c.dom.* interfaces are included in this Jar. They come from the W3C and define the Document Object Model standard API's for working with a tree of XML nodes.

#### Question 2

Now, if I wish to use the @code as a key, I use

    <xsl:template match="aTextNode">
        ...
       <xsl:param name="labelCode" select="@code"/>
         <xsl:value-of
     select="document('messages.xml')/messages/msg[@id=$labelCode and
     @lang=$lang]"/>
        ...
       </xsl:template>

that works too, but I was wondering if there isn't a way to use the '@code' directly in the 'document()' line?

#### Answer 2

This is what the current() function is useful for. Rather than:

    <xsl:param name="labelCode" select="@code"/>
    <xsl:value-of
     select="document('messages.xml')/messages/msg[@id=$labelCode and
     @lang=$lang]"/>

you can do:

    <xsl:value-of
    select="document('messages.xml')/messages/msg[@id=current()/@code
                          and @lang = $lang]"/>

#### Question 3

And finally, another question : it is - or will it be - possible to retrieve the data stored in messages.xml from the database ? How is the 'document()' instruction going to work where listener and servlet will run inside the database ?

#### Answer 3

Sure. By the spec, the XSL-T engine should read and cache the document referred to in the document() function. It caches the parsed document based on the string-form of the URI you pass in, so here's how you can achieve a database-based message lookup:

1. CREATE TABLE MESSAGES( lang VARCHAR2(2), code NUMBER, message VARCHAR2(200));

2. Create an xsql page like "msg.xsql" below:

       <xsql:query lang="en" xmlns:xsql="urn:oracle-xsql" connection="demo"
                   row-element="" rowset-element="">
             select message
               from messages
              where lang = '{@lang}'
                and code = {@code}
       </xsql:query>

3. Create a stylesheet that uses msg.xsql in the document() function like:

       <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       version="1.0">
         <xsl:template match="/">
         <html><body>
           In English my name is
             <xsl:call-template name="msg">
                <xsl:with-param name="code">101</xsl:with-param>
             </xsl:call-template><br/>
           En espanol mi nombre es
             <xsl:call-template name="msg">
                <xsl:with-param name="code">101</xsl:with-param>
                <xsl:with-param name="lang">es</xsl:with-param>
             </xsl:call-template><br/>
           En fran&#231;ais, je m'appelle
             <xsl:call-template name="msg">
                <xsl:with-param name="code">101</xsl:with-param>
                <xsl:with-param name="lang">fr</xsl:with-param>
             </xsl:call-template><br/>
           In italiano, mi chiamo
             <xsl:call-template name="msg">
                <xsl:with-param name="code">101</xsl:with-param>
                <xsl:with-param name="lang">it</xsl:with-param>
             </xsl:call-template>
         </body></html>
         </xsl:template>
         <xsl:template name="msg">
           <xsl:param name="lang">en</xsl:param>
           <xsl:param name="code"/>
           <xsl:variable name="msgurl"
       select="concat('http://xml/msg.xsql?lang=',$lang,'&amp;code=',$code)"/>
           <xsl:value-of select="document($msgurl)/MESSAGE"/>
         </xsl:template>
       </xsl:stylesheet>

4. Try it out at http://xml/testmessage.xsql

This is great if you want to fetch the message from over the web. Alternatively, you could use the msg.xsql above but include it in your XSQL Page if that makes sense using:

    <xsql:include-xsql href="msg.xsql?lang={@lang}&amp;code={@code}"/>

Or you could write your own custom action handler to use JDBC to fetch the message and include it in the XSQL page yourself.

### Moving Complex XML Documents to a Database

#### Question

I am moving XML documents to an Oracle database. The documents are fairly complex. Can an XML document and the Oracle Development Kit (XDK) generate a possible DDL format for how the XML Document should be stored in the database, ideally generating an Object-Relational Structure. Does anyone know of a tool that can do this?

#### Answer a

The best way may be to use the Class Generator. Use XML-SQL Utility if DTD files are not already created. You'll still have to write a mapping program.

Another method is to create views and write stored procedures to update multiple tables. Unfortunately, you'll have to create your tables and views beforehand in either case.

##### BC4J

Business Components for Java (BC4J) framework provides a general, meta-data-driven solution for mapping E-Commerce XML Messages into and out of the database. BC4J has a technical whitepaper on its features available at http://technet.oracle.com/products/jdev/info/techwp20/wp.html.

It is a Pure-Java, XML-Based business components framework for making building E-Commerce applications easier. It is a Java framework usable on its own, but also has tight development support built-into JDeveloper 3.0 IDE, available for download from http://technet.oracle.com/software/htdocs/devlic.htm.

BC4J lets you flexibly map hierarchies of SQL-based "view components" to underlying business components that manage all application behavior (rules and processes) in a uniform way. It also supports *dynamic* functionality, so most of its features can be driven completely off XML metadata.

You can build a layer which flexibly maps any XML Document into and out of the database using this framework. One key benefit is that when XML Documents are put into the system, they automatically can have all the same business rules validated.

| Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
Library | Service | Contents | Index