Skip Headers

Oracle® Application Server Reports Services Publishing Reports to the Web 10g Release 2 (10.1.2) B14048-02 |
| Library | Product | Contents | Index

Previous | Next |

# 16 Customizing Reports with XML

Extensible Markup Language (XML) is designed to improve the functionality of the Web by providing a method to promote detailed information identification. It is actually a metalanguage (a language used for describing other languages) and can be used to design customized markup languages for different type of documents.

XML documents are composed of both markup and content:

- Elements are the building blocks of XML. An element instance is a structure that contains tags (a main tag and appropriate nested tags), attributes, and the element's content nested between the tags.

- Tags are used to define the element and the content within it.

- Attributes provide extra information for each tag.

XML customizations enable you to modify reports at runtime without changing the original report. With the addition of the `CUSTOMIZE` keyword to your runtime command line, you can call a customization file to add to or change a report's layout or data model. One XML customization file can perform all of these tasks or any combination of them. You can even use XML to build a report data model for inclusion in a custom JSP-based report.

By creating and applying different XML customizations, you can alter the report output on a per user or per user group basis. You can use the same report to generate different output depending upon the audience.

When you apply an XML customization to a report, you have the option of saving the combined definition to a file. As a result, you can use XML customizations to make batch updates to existing reports. You can quickly update a large number of reports without having to open each file in Reports Builder.

OracleAS Reports Services extends the possible types of Oracle Reports XML customizations by enabling you to create an entire reports data model in XML. This includes the creation of multiple data sources, linking between data sources, and group hierarchies within each data source. Data model support through Oracle Reports XML customization means that any data model that can be created with Reports Builder can now be created by specifying XML. Additionally, all properties that can be set against data model objects can now be set using XML.

This chapter discusses the ways you can use XML to customize reports on the fly and to build data models. It includes the following sections:

- Customization Overview

- Creating XML Customizations

- Creating XML Data Models

- Using XML Files at Runtime

- Debugging XML Report Definitions

This chapter lists and provides examples of the supported elements in the `reports.dtd` file. However, only some of the attributes of these elements are listed.

For more information, either on the additional attributes or on the Oracle Reports XML elements, tags, and attributes, refer to the following sources:

- The `reports.dtd` file lists all the Oracle Reports XML elements, tags, and attributes and, where present, the attributes' default values. The `reports.dtd` file is located in `ORACLE_HOME``\reports\dtd\` on both Windows and UNIX platforms. Many of the sub-elements include symbols that denote usage rules. For example:

  - A plus sign (+) means you can have one or more of this type of element in your XML file.

  - An asterisk (*) means you can have from zero to many of this type of element in your XML file.

  - A question mark (?) means you can have either zero or one of this type of element in your XML file.

  - No mark means the element is required, and you can have one and only one of this type of element in your XML file.

  If multiple sub-elements are enclosed in parentheses and followed by a symbol, the symbol applies to all enclosed sub-elements.

- For descriptions of selected Oracle Reports XML tags, see topic "Oracle Reports XML tags" in the Reference section of the Oracle Reports online Help.

- Build a report that includes the type of customization you are trying to build, save the report as XML, and view the saved file in a text editor. This provides an excellent means of seeing Oracle Reports XML in action and provides you with examples of the more complex models you may wish to build.

## 16.1 Customization Overview

By using the Oracle Reports XML tags, you can customize reports created using Reports Builder.

Note: Although it is possible to create an entire report manually using the Oracle Reports XML tags, only manually created customizations and data models are documented and supported.

Creating and applying an XML customization is a three-step process:

1. Create a customization file using Oracle Reports XML tags.

   You can create this customization by building a report using Reports Builder then saving your report as XML. You can also build the customization manually, with any sort of text editor or a sophisticated XML editor, as long as you include the XML tags that are required for the particular Oracle Reports customization.

2. Store the XML customization in a location that is accessible to OracleAS Reports Services.

3. Apply the XML customization to another report with the `CUSTOMIZE` command line keyword or the `SRW.APPLY_DEFINITION` built-in procedure, or run the XML customization by itself (if it contains a complete report definition) with the `REPORT` (or `MODULE`) command line keyword.

   See Also: Section A.3.20, "CUSTOMIZE"

   Note: For a description of the `SRW` built-in package, including the `SRW.APPLY_DEFINITION` built-in procedure, see the Oracle Reports online Help.

## 16.2 Creating XML Customizations

This section provides examples of various report customizations. It includes examples of:

- Required XML Tags

- Changing Styles

- Changing a Format Mask

- Adding Formatting Exceptions

- Adding Program Units and Hyperlinks

- Adding a New Query and Using the Result in a New Header Section

- Encoding the URL

### 16.2.1 Required XML Tags

Every XML customization must contain the following required tag pair:

    <report></report>

For example, the following is the most minimal XML customization possible:

    <report name="emp" DTDVersion="9.0.2.0.0">
    </report>

This XML customization would have a null effect if applied to a report because it contains nothing. It can be parsed because it has the needed tags, but it is useful only as an example of the required tags.

The `<report>` tag indicates the beginning of the report customization, its name, and the version of the Data Type Dictionary (DTD) file that is being used with this XML customization. The `</report>` tag indicates the end of the report customization.

The `report` tag's `name` attribute can be any name you wish, either the name of the report the XML file will customize, or any other name.

This example represents a minimal use of the `<report>` tag. The `<report>` tag also has many attributes, most of which are implied and need not be specified. The only required `<report>` attribute is `DTDVersion`.

Note: To apply an XML customization file to modify an existing report trigger or to create a new report trigger, you must specify the relevant trigger attribute of the `<report>` tag: For example, to modify or create a Before Report trigger, use the `beforeReportTrigger` attribute:
    <report DTDVersion="9.0.2.0.0" beforeReportTrigger="BeforeReport">
If you do not specify this attribute when you want to apply an XML customization file to modify or create a report trigger, the report trigger PL/SQL code will be treated as a local (independent) function when the XML customization file is applied to your report.

A full report definition requires both a data model and a layout and therefore also requires the following tags and their contents:

- `<data></data>`

- `<layout></layout>`

The `data` tag has no accompanying attributes. The `layout` tag has two attributes, both of which are required: `panelPrintOrder` and `direction`. If you use the default values for these attributes (respectively `acrossDown` and `default`), you don't need to specify them. Examples of the `data` and `layout` elements are provided in the following sections.

### 16.2.2 Changing Styles

The example in this section demonstrates the use of XML to change the fill and line colors used for report fields `F_Mincurrent_pricePersymbol` and `F_Maxcurrent_pricePersymbol`.

    <report name="anyName" DTDVersion="9.0.2.0.0">
      <layout>
        <section name="main">
          <field name="F_Mincurrent_pricePersymbol"
                 source="Mincurrent_pricePersymbol"
                 lineColor="black"
                 fillColor="r100g50b50"/>
          <field name="F_Maxcurrent_pricePersymbol"
                 source="Maxcurrent_pricePersymbol"
                 lineColor="black"
                 fillColor="r100g50b50"/>
        </section>
      </layout>
    </report>

We assume in this example that the `section` and `field` tags' name attributes match the names of fields in the Main section of the report this XML file will customize. In keeping with this assumption, the other attributes of the `field` tag will be applied only to the fields of the same name in the report's Main section.

### 16.2.3 Changing a Format Mask

The example in this section demonstrates the use of XML to change the format mask used for a report field `f_trade_date`.

    <report name="anyName" DTDVersion="9.0.2.0.0">
      <layout>
        <section name="main">
          <field name="f_trade_date"
                 source="trade_date"
                 formatMask="MM/DD/RR"/>
        </section>
      </layout>
    </report>

Notice that the `field` tag provides its own closure (`/>`). If the `field` tag used additional sub-tags, you would close it with `</field>`.

### 16.2.4 Adding Formatting Exceptions

The example in this section demonstrates the use of XML to add a formatting exception to highlight values greater than 10 in a report's `f_p_e` and `f_p_e1` fields.

    <report name="anyName" DTDVersion="9.0.2.0.0">
      <layout>
        <section name="main">
          <field name="f_p_e" source="p_e">
          <exception textColor="red">
           <condition source="p_e" operator="gt" operand1="10"/>
            </exception>
          </field>
          <field name="f_p_e1" source="p_e">
            <exception textColor="blue">
           <condition source="p_e" operator="gt" operand1="10"/>
            </exception>
          </field>
        </section>
      </layout>
    </report>

In this example, the value for `operator` is `gt`, for greater than. Operators include those listed in Table 16-1:

Table 16-1 Values for the operator Attribute

Value | Usage
--- | ---
`eq` | equal
`lt` | less than
`lteq` | less than or equal to
`neq` | not equal to
`gt` | greater than
`gteq` | greater than or equal to
`btw` | between
`notBtw` | not between
`like` | like
`notLike` | not like
`null` | null
`notNull` | not null

Notice also that, unlike the previous example, the `field` tags in this example uses sub-tags, and, consequently, closes with `</field>`, rather than a self-contained closure (`/>`).

### 16.2.5 Adding Program Units and Hyperlinks

The example in this section demonstrates the use of XML to add a program unit to a report, which in turn adds a hyperlink from the employee social security number (`:SSN`) to employee details.

    <report name="anyName" DTDVersion="9.0.2.0.0">
      <layout>
        <section name="header">
          <field name="F_ssn1" source="ssn1">
            <advancedLayout formatTrigger="F_ssn1FormatTrigger"/>
          </field>
        </section>
        <section name="main">
          <field name="F_ssn" source="ssn">
            <advancedLayout formatTrigger="F_ssnFormatTrigger"/>
          </field>
        </section>
      </layout>
      <programUnits>
        <function name="F_ssn1FormatTrigger">
          <textSource>
            <![CDATA[
              function F_ssn1FormatTrigger return boolean is
              begin
                SRW.SET_HYPERLINK('#EMP_DETAILS_&<' || LTRIM(TO_CHAR(:SSN)) || '>');
                return (TRUE);
              end;
            ]]>
          </textSource>
        </function>
        <function name="F_ssnFormatTrigger">
          <textSource>
            <![CDATA[
              function F_ssnFormatTrigger return boolean is
              begin
                SRW.SET_LINKTAG('EMP_DETAILS_&<' || LTRIM(TO_CHAR(:SSN)) || '>');
                return (TRUE);
              end;
            ]]>
          </textSource>
        </function>
      </programUnits>
    </report>

A `CDATA` tag is used around the PL/SQL to distinguish it from the XML. Use the same tag sequence when you embed HTML in your XML file. In this example, the functions are referenced by name from the `formatTrigger` attribute of the `advancedLayout` tag.

### 16.2.6 Adding a New Query and Using the Result in a New Header Section

The example in this section demonstrates the use of XML to add a new query to a report and a new header section that makes use of the query result.

    <report name="ref" DTDVersion="9.0.2.0.0">
      <data>
        <dataSource name="Q_summary">
          <select>select portid ports, locname locations from portdesc</select>
        </dataSource>
      </data>
      <layout>
        <section name="header">
          <tabular name="M_summary" template="BLAFbeige.tdf">
          <labelAttribute font="Arial" fontSize="10"
                            fontStyle="bold" textColor="white"/>
          <field name="F_ports" source="ports" label="Port IDs"
                   font="Arial" fontSize="10"/>
          <field name="F_locations" source="locations" label="Port Names"
                   font="Arial" fontSize="10"/>
          </tabular>
        </section>
      </layout>
    </report>

This example XML can be run by itself because it has both a data model and a complete layout.

Use aliases in your SELECT statements to ensure the uniqueness of your column names. If you do not use an alias, then the default name of the report column is used and could be something different from the name you expect (for example, portid1 instead of portid). This becomes important when you must specify the `source` attribute of the `field` tag, which requires you to supply the correct name of the source column (the field).

The `labelAttribute` element defines the formatting for the field labels in the layout. Because it lies outside of the open and close `field` tag , it applies to all the labels in the tabular layout. If you wanted it to pertain to only one of the fields, then you place it inside the `<field></field>` tag pair. If there is both a global and local `labelAttribute` element (one outside and one inside the `<field></field>` tag pair), the local overrides the global.

### 16.2.7 Encoding the URL

To ensure that spaces and control characters are passed correctly, you may need to turn URL encoding on or off for the fields in your report. You can turn URL encoding on or off with the `RW:FIELD` tag in a report:

    <rw:field
    ...
    urlEncode=yes|no
    ...
    />

The default value for `urlEncode` is `no`.

## 16.3 Creating XML Data Models

OracleAS Reports Services introduces a greater level of sophistication in the types of data models you can create using Oracle Reports XML tags. Use XML for:

- Creating Multiple Data Sources

- Linking Between Data Sources

- Creating Group Hierarchies Within Each Data Source

- Creating Cross-Product (Matrix) Groups

- Creating Formulas, Summaries, and Placeholders at Any Level

- Creating Parameters

This section provides examples of these uses of XML.

In addition to these data model types, OracleAS Reports Services provides support for using PL/SQL in your XML. This includes support for local program units, report-level triggers, and attached PL/SQL libraries.

### 16.3.1 Creating Multiple Data Sources

The `<data>` tag now supports the creation of multiple data sources as well as the new pluggable data sources. Each data source is enclosed within its own `<dataSource>` tag. The data type definition for the `dataSource` element is:

    <!ELEMENT dataSource
      ((select|plugin|plsql),
      comment?,
      displayInfo?,
      formula*,
      group*)>
    <!ATTLIST dataSource
      name CDATA #IMPLIED
      defaultGroupName CDATA #IMPLIED
      maximumRowsToFetch CDATA #IMPLIED>

The following example creates two SQL data sources and names them Q_1 and Q_2. It also creates all the necessary columns for the data sources and the default group—giving the group the specified `defaultGroupName` or defaulting its own name if `defaultGroupName` is not specified.

    <report name="anyname" DTDVersion="9.0.2.0.0">
      <data>
        <dataSource name="Q_1" defaultGroupName="G_DEPARTMENTS">
          <select>
          select * from departments
          </select>
        </dataSource>
        <dataSource name="Q_2" defaultGroupName="G_EMPLOYEES">
          <select>
          select * from employees
        </select>
        </dataSource>
      </data>
    </report>

### 16.3.2 Linking Between Data Sources

In the presence of multiple data sources, it may be desirable to link the data sources together to create the appropriate data model. Oracle Reports data model link objects have also been exposed through Oracle Reports XML. They support both group- and column-level links. You can specify any number of links to create the required data model.

The data type definition for the `link` element is:

    <!ELEMENT link EMPTY>
    <!ATTLIST link
      name CDATA #IMPLIED
      parentGroup CDATA #IMPLIED
      parentColumn CDATA #IMPLIED
      childQuery CDATA #IMPLIED
      childColumn CDATA #IMPLIED
      condition (eq|lt|neq|gt|gteq|like|notLike) "eq"
      sqlClause (startWith|having|where) "where">

The `link` element is placed within a `data` element and can link any two `dataSource` objects defined within the `data` element. For example:

    <report name="anyname" DTDVersion="9.0.2.0.0">
      <data>
        <dataSource name="Q_1" defaultGroupName="G_DEPARTMENTS">
          <select>
            select * from departments
          </select>
        </dataSource>
        <dataSource name="Q_2" defaultGroupName="G_EMPLOYEES">
          <select>
            select * from employees
          </select>
        </dataSource>
        <link name="L_1" parentGroup="G_DEPARTMENTS"
              parentColumn="DEPARTMENT_ID" childQuery="Q_2"
              childColumn="DEPARTMENT_ID1" condition="eq" sqlClause="where"/>
      </data>
    </report>

Within the `link` element, Oracle Reports defaulting mechanism recognizes `DEPARTMENT_ID1` as an alias to the `DEPARTMENT_ID` column in the `EMPLOYEES` table without your having to explicitly create such an alias.

### 16.3.3 Creating Group Hierarchies Within Each Data Source

With OracleAS Reports Services, the complete group hierarchy is available to you. You can specify all the columns within each group and break the order of those columns. You can use formulas, summaries, and placeholders to further customize the objects within groups.

The data type definition for the `group` element is:

    <!ELEMENT group
      (field|exception|rowDelimiter|xmlSettings|displayInfo|dataItem|formula|
      summary|placeholder|filter|comment)*>
    <!ATTLIST group
      name CDATA #IMPLIED
      fillColor CDATA #IMPLIED
      lineColor CDATA #IMPLIED
      formatTrigger CDATA #IMPLIED>

The following example demonstrates the use of a `group` element to create a break group under a data source.

    <report name="anyname" DTDVersion="9.0.2.0.0">
      <data>
        <dataSource name="Q_1">
          <select>
            select * from employees
          </select>
          <group name="G_DEPARTMENTS">
            <dataItem name="DEPARTMENT_ID"/>
          </group>
          <group name="G_EMPLOYEES">
            <dataItem="EMPLOYEE_ID"/>
            <dataItem="FIRST_NAME"/>
            <dataItem="LAST_NAME"/>
            <dataItem="JOB_ID"/>
            <dataItem="MANAGER_ID"/>
            <dataItem="HIRE_DATE"/>
            <dataItem="SALARY"/>
            <dataItem="COMMISSION_PCT"/>
          </group>
        </dataSource>
      </data>
    </report>

### 16.3.4 Creating Cross-Product (Matrix) Groups

Cross-product groups allow you to define a matrix of any number of groups in the data model. The dimension groups in a cross product may exist in the same data source or may be combined from different data sources to create a matrix. In support of this flexibility, the `<crossProduct>` tag is placed within the `<data>` tag after all the data sources and groups have been created.

The data type definition for the `crossProduct` element is:

    <!ELEMENT crossProduct
      (xmlSettings|displayInfo|dimension|(formula|summary|placeholder)*|comment)*>
    <ATTLIST crossProduct
      name CDDATA #IMPLIED
      mailText CDDATA #IMPLIED>

The following example demonstrates the creation of a single-query matrix.

    <report name="anyname" DTDVersion="9.0.2.0.0">
      <data>
        <dataSource name="Q_1">
          <select>
            select * from employees
          </select>
          <group name="G_DEPARTMENTS">
            <dataItem name="DEPARTMENT_ID"/>
          </group>
          <group name="G_JOB_ID>
            <dataItem name="JOB_ID"/>
          </group>
          <group name="G_MANAGER_ID">
            <dataItem name="MANAGER_ID"
          </group>
          <group name="G_EMPLOYEE_ID">
            <dataItem name="EMPLOYEE_ID"/>
          <dataItem name="FIRST_NAME"/>
            <dataItem name="LAST_NAME"/>
            <dataItem name="HIRE_DATE"/>
            <dataItem name="SALARY"/>
            <dataItem name="COMMISSION_PCT"/>
          </group>
        </dataSource>
        <crossProduct name="G_Matrix">
          <dimension>
            <group name="G_DEPARTMENTS">
          </dimension>
          <dimension>
          <group name="G_JOB_ID">
          </dimension>
          <dimension>
          <group name="G_MANAGER_ID">
          </dimension>
        </crossProduct>
      </data>
    </report>

### 16.3.5 Creating Formulas, Summaries, and Placeholders at Any Level

You can place formulas, summaries, and placeholders at any level within the data model. Additionally, you have complete control over all the attributes for each of these objects.

The following example demonstrates the creation of a report-level summary whose source is based on a group-level formula column.

    <report name="anyname" DTDVersion="9.0.2.0.0">
      <data>
        <dataSource name="Q_1">
          <select>
            select * from employees
          </select>
          <group name="G_EMPLOYEES">
            <dataItem="EMPLOYEE_ID"/>
            <dataItem name="EMPLOYEE_ID"/>
            <dataItem name="FIRST_NAME"/>
            <dataItem name="LAST_NAME"/>
            <dataItem name="HIRE_DATE"/>
            <dataItem name="SALARY"/>
            <dataItem name="COMMISSION_PCT"/>
            <dataItem name="DEPARTMENT_ID"/>
            <formula name="CF_REMUNERATION" source="cf_1formula"
              datatype="number" width="20" precision="10"/>
          </group>
        </dataSource>
        <summary name="CS_REPORT_LEVEL_SUMMARY" function="sum" width="20"
          precision="10" reset="report" compute="report"/>
      </data>
      <programUnits>
        <function name="cf_1formula" returnType="number">
          <textSource>
            <![CDATA[
              function CF_1Formula return Number is
              begin
              return (:salary + nvl(:commission_pct,0));
              end;
            ]]>
          </textSource>
        </function>
      </programUnits>
    </report>

### 16.3.6 Creating Parameters

In Oracle Reports XML, the `parameter` element is placed between open and close `data` tags. The data type definition for the `parameter` element is:

    <!ELEMENT parameter (comment?|listOfValues?)>
    <!ATTLIST parameter
      name CDATA #REQUIRED
      datatype (number|character|date) "number"
      width CDATA "20"
      scale CDATA "0"
      precision CDATA "0"
      initialValue CDATA #IMPLIED
      inputMask CDATA #IMPLIED
      validationTrigger CDATA #IMPLIED
      label CDATA #IMPLIED
      defaultWidth CDATA #IMPLIED
      defaultHeight CDATA #IMPLIED>

The following example demonstrates a dynamic list of values (LOV), an initial value, and a validation trigger.

    <report name="anyname" DTDVersion="9.0.2.0.0">
      <data>
        <dataSource name="Q_1" defaultGroupName="G_DEPARTMENTS">
          <select>
            select * from departments
          </select>
          </dataSource>
            <parameter name="P_LAST_NAME" datatype="character" precision="10"
              initialValue="SMITH" validationTrigger="p_last_namevalidtrigger"
              defaultWidth="0" defaultHeight="0">
              <listOfValues restrictToList="yes">
                <selectStatement hideFirstColumn="yes">
                  <![CDATA[select last_name, 'last_name||'-'||employee_id'
                    from employees]]>
                </selectStatement>
              </listOfValues>
            </parameter>
      </data>
      <programUnits>
        <function name="p_last_namevalidtrigger" returnType="character">
          <textSource>
            <![CDATA[function P_LAST_NAMEValidTrigger return boolean is
              last_name char(20);
              begin
                select count(*) into last_name from employees
                  where upper(last_name)=upper(:p_last_name);
                exception when OTHERS then return(FALSE);
                end;
                return(TRUE);
              end;
            ]]>
          </textSource>
        </function>
      </programUnits>
    </report>

## 16.4 Using XML Files at Runtime

Once you have created your Oracle Reports XML customization file, you can use it in the following ways:

- You can apply XML report definitions to RDF or other XML files at runtime by specifying the `CUSTOMIZE` command line keyword or the `SRW.APPLY_DEFINITION` built-in procedure. Refer to Section 16.4.1, "Applying an XML Report Definition at Runtime" for more information.

  Note: Oracle Reports does not support XML customizations of REP files.

- You can run an XML report definition by itself (without another report) by specifying the `REPORT` (or `MODULE`) command line keyword. Refer to Section 16.4.2, "Running an XML Report Definition by Itself" for more information.

- You can use `rwconverter` to make batch modifications using the `CUSTOMIZE` command line keyword. Refer to Section 16.4.3, "Performing Batch Modifications" for more information.

The following sections describe each of the cases in more detail and provide examples.

### 16.4.1 Applying an XML Report Definition at Runtime

To apply an XML report definition to an RDF or XML file at runtime, you can use the `CUSTOMIZE` command line keyword or the `SRW.APPLY_DEFINITION` built-in procedure. `CUSTOMIZE` can be used with `rwclient`, `rwrun`, `rwbuilder`, `rwconverter`, and URL report requests.

Note: Refer to Section 16.4.3, "Performing Batch Modifications" for more information about using `CUSTOMIZE` with `rwconverter`.

#### 16.4.1.1 Applying One XML Report Definition

The following command line sends a job request to OracleAS Reports Services and applies an XML report definition, `emp.xml`, to an RDF file, `emp.rdf`. In this example, the `CUSTOMIZE` keyword refers to a file located in a Windows directory path. For UNIX, specify the path according to UNIX standards (that is, `myreports/emp.xml`).

    rwclient REPORT=emp.rdf CUSTOMIZE=\myreports\emp.xml
      USERID=username/password@my_db DESTYPE=file DESNAME=emp.pdf
      DESFORMAT=PDF SERVER=server_name

When you use `rwrun`, the Reports Runtime command, the equivalent command line would be:

    rwrun USERID=username/password@my_db REPORT=emp.rdf
       CUSTOMIZE=\myreports\emp.xml DESTYPE=file DESNAME=emp.pdf
       DESFORMAT=PDF

When testing your XML report definition, it is sometimes useful to run your report requests with additional options to create a trace file. For example:

    TRACEFILE=emp.log TRACEMODE=trace_replace TRACEOPTS=trace_app

See Also: Section A.3.114, "TRACEFILE", Section A.3.115, "TRACEMODE", and Section A.3.116, "TRACEOPTS"

Note: Unless you care to change the default, it isn't necessary to include a trace in the command line if you have specified a default trace option in the Reports Server configuration file.

The trace file provides a detailed listing of the creation and formatting of the report objects.

#### 16.4.1.2 Applying Multiple XML Report Definitions

You can apply multiple XML report definitions to a report at runtime by providing a list with the `CUSTOMIZE` command line keyword. The following command line sends a job request to OracleAS Reports Services that applies two XML report definitions, `EMP0.XML` and `EMP1.XML`, to an RDF file, `EMP.RDF`:

    rwclient REPORT=emp.rdf
      CUSTOMIZE="(d:\corp\myreports\emp0.xml,d:\corp\myreports\emp1.xml)"
      USERID=username/password@my_db DESTYPE=file DESNAME=emp.pdf
      DESFORMAT=PDF SERVER=server_name

Note: In this example, the `CUSTOMIZE` value demonstrates a directory path to files stored on a Windows platform. For UNIX, use that platform's standard for specifying directory paths (that is, forward slashes instead of backward).

If you were using Reports Runtime, then the equivalent command line would be:

    rwrun REPORT=emp.rdf
      CUSTOMIZE="(D:\CORP\MYREPOORTS\EMP0.XML,D:\CORP\MYREPORTS\EMP1.XML)"
      USERID=username/password@my_db DESTYPE=file DESNAME=emp.pdf
      DESFORMAT=PDF

#### 16.4.1.3 Applying an XML Report Definition in PL/SQL

To apply an XML report definition to an RDF file in PL/SQL, use the `SRW.APPLY_DEFINITION` and `SRW.ADD_DEFINITION` built-in procedures in the Before Parameter Form or After Parameter Form trigger. The following sections provide examples of these built-in procedures.

Note: For a description of the `SRW` built-in package, including the `SRW.APPLY_DEFINITION` and `SRW.ADD_DEFINITION` built-in procedures, and more information about report triggers, see the Oracle Reports online Help.

##### 16.4.1.3.1 Applying an XML Definition Stored in a File

To apply XML that is stored in the file system to a report, use the `SRW.APPLY_DEFINITION` built-in procedure in the Before Parameter Form or After Parameter Form triggers of the report.

On Windows:

    SRW.APPLY_DEFINITION ('%ORACLE_HOME%\TOOLS\DOC\US\RBBR\COND.XML');

On UNIX:

    SRW.APPLY_DEFINITION ('$ORACLE_HOME/TOOLS/DOC/US/RBBR/COND.XML');

When the report is run, the trigger executes and the specified XML file is applied to the report.

##### 16.4.1.3.2 Applying an XML Definition Stored in Memory

To create an XML report definition in memory, you must add the definition to the document buffer using `SRW.ADD_DEFINITION` before applying it using the `SRW.APPLY_DEFINITION` built-in procedure.

The following example illustrates how to build up and apply several definitions in memory based upon parameter values entered by the user. The PL/SQL in this example is used in the After Parameter Form trigger of a report called `videosales_custom.rdf`.

The `videosales_custom.rdf` file contains PL/SQL in its After Parameter Form trigger that does the following:

- Conditionally highlights fields based upon parameter values entered by the user at runtime.

- Changes number format masks based upon parameter values entered by the user at runtime.

The following tips are useful when looking at this example:

- Each time you use the `SRW.APPLY_DEFINITION` built-in procedure, the document buffer is flushed and you must begin building a new XML report definition with `SRW.ADD_DEFINITION`.

- Notice the use of the parameters `hilite_profits`, `hilite_costs`, `hilite_sales`, and `money_format` to determine what to include in the XML report definition. The `hilite_profits`, `hilite_costs`, and `hilite_sales` parameters are also used in the formatting exceptions to determine which values to highlight.

- Because of the upper limit on the size of VARCHAR2 columns (4000 bytes), you might need to spread very large XML report definitions across several columns. If so, then you might have to create several definitions in memory and apply them separately rather than creating one large definition and applying it once.

    function AfterPForm return boolean is
    begin
      SRW.ADD_DEFINITION('<report name="vidsales_masks"
      author="Generated" DTDVersion="9.0.2.0.0">');
      IF :MONEY_FORMAT='$NNNN.00' THEN
        SRW.ADD_DEFINITION('<layout>');
        SRW.ADD_DEFINITION('<section name="main">');
        SRW.ADD_DEFINITION('<field name="F_TOTAL_PROFIT" source="TOTAL_PROFIT"
          formatMask="LNNNNNNNNNNN0D00"/>');
        SRW.ADD_DEFINITION('<field name="F_TOTAL_SALES" source="TOTAL_SALES"
          formatMask="LNNNNNNNNNNN0D00"/>');
        SRW.ADD_DEFINITION('<field name="F_TOTAL_COST" source="TOTAL_COST"
          formatMask="LNNNNNNNNNNN0D00"/>');
        SRW.ADD_DEFINITION('<field name="F_SumTOTAL_PROFITPerCITY"
          source="SumTOTAL_PROFITPerCITY" formatMask="LNNNNNNNNNNN0D00"/>');
        SRW.ADD_DEFINITION('<field name="F_SumTOTAL_SALESPerCITY"
          source="SumTOTAL_SALESPerCITY" formatMask="LNNNNNNNNNNN0D00"/>');
        SRW.ADD_DEFINITION('<field name="F_SumTOTAL_COSTPerCITY"
          source="SumTOTAL_COSTPerCITY" formatMask="LNNNNNNNNNNN0D00"/>');
        SRW.ADD_DEFINITION('</section>');
        SRW.ADD_DEFINITION('</layout>');
      ELSIF :MONEY_FORMAT='$NNNN' THEN
        SRW.ADD_DEFINITION('<layout>');
        SRW.ADD_DEFINITION('<section name="main">');
        SRW.ADD_DEFINITION('<field name="F_TOTAL_PROFIT" source="TOTAL_PROFIT"
          formatMask="LNNNNNNNNNNN0"/>');
        SRW.ADD_DEFINITION('<field name="F_TOTAL_SALES" source="TOTAL_SALES"
          formatMask="LNNNNNNNNNNN0"/>');
        SRW.ADD_DEFINITION('<field name="F_TOTAL_COST" source="TOTAL_COST"
          formatMask="LNNNNNNNNNNN0"/>');
        SRW.ADD_DEFINITION('<field name="F_SumTOTAL_PROFITPerCITY"
          source="SumTOTAL_PROFITPerCITY" formatMask="LNNNNNNNNNNN0"/>');
        SRW.ADD_DEFINITION('<field name="F_SumTOTAL_SALESPerCITY"
          source="SumTOTAL_SALESPerCITY" formatMask="LNNNNNNNNNNN0"/>');
        SRW.ADD_DEFINITION('<field name="F_SumTOTAL_COSTPerCITY"
          source="SumTOTAL_COSTPerCITY" formatMask="LNNNNNNNNNNN0"/>');
        SRW.ADD_DEFINITION('</section>');
        SRW.ADD_DEFINITION('</layout>');
      END IF;
      SRW.ADD_DEFINITION('</report>');
      SRW.APPLY_DEFINITION;
      SRW.ADD_DEFINITION('<report name="vidsales_hilite_costs" author="Generated"
        DTDVersion="9.0.2.0.0">');
      IF :HILITE_COSTS <> 'None' THEN
        SRW.ADD_DEFINITION('<layout>');
        SRW.ADD_DEFINITION('<section name="main">');
        SRW.ADD_DEFINITION('<field name="F_TOTAL_COST" source="TOTAL_COST">');
        SRW.ADD_DEFINITION('<exception textColor="red">');
        SRW.ADD_DEFINITION('<condition source="TOTAL_COST" operator="gt"
          operand1=":hilite_costs"/>');
        SRW.ADD_DEFINITION('</exception>');
        SRW.ADD_DEFINITION('</field>');
        SRW.ADD_DEFINITION('</section>');
        SRW.ADD_DEFINITION('</layout>');
      END IF;
      SRW.ADD_DEFINITION('</report>');
      SRW.APPLY_DEFINITION;
      SRW.ADD_DEFINITION('<report name="vidsales_hilite_sales" author="Generated"
        DTDVersion="9.0.2.0.0">');
      IF :HILITE_SALES <> 'None' THEN
        SRW.ADD_DEFINITION('<layout>');
        SRW.ADD_DEFINITION('<section name="main">');
        SRW.ADD_DEFINITION('<field name="F_TOTAL_SALES" source="TOTAL_SALES">');
        SRW.ADD_DEFINITION('<exception textColor="red">');
        SRW.ADD_DEFINITION('<condition source="TOTAL_SALES" operator="gt"
          operand1=":hilite_sales"/>');
        SRW.ADD_DEFINITION('</exception>');
        SRW.ADD_DEFINITION('</field>');
        SRW.ADD_DEFINITION('</section>');
        SRW.ADD_DEFINITION('</layout>');
      END IF;
      SRW.ADD_DEFINITION('</report>');
      SRW.APPLY_DEFINITION;
      SRW.ADD_DEFINITION('<report name="vidsales_hilite_profits" author="Generated"
        DTDVersion="9.0.2.0.0">');
      IF :HILITE_PROFITS <> 'None' THEN
        SRW.ADD_DEFINITION('<layout>');
        SRW.ADD_DEFINITION('<section name="main">');
        SRW.ADD_DEFINITION('<field name="F_TOTAL_PROFIT" source="TOTAL_PROFIT">');
        SRW.ADD_DEFINITION('<exception textColor="red">');
        SRW.ADD_DEFINITION('<condition source="TOTAL_PROFIT" operator="gt"
          operand1=":hilite_profits"/>');
        SRW.ADD_DEFINITION('</exception>');
        SRW.ADD_DEFINITION('</field>');
        SRW.ADD_DEFINITION('</section>');
        SRW.ADD_DEFINITION('</layout>');
      END IF;
      SRW.ADD_DEFINITION('</report>');
      SRW.APPLY_DEFINITION;
      return (TRUE);
    end;

### 16.4.2 Running an XML Report Definition by Itself

To run an XML report definition by itself, you send a request with an XML file specified in the `REPORT` (or `MODULE`) option. The following command line sends a job request to OracleAS Reports Services to run a report, `emp.xml`, by itself:

    rwclient USERID=username/password@my_db
      REPORT=c:\corp\myreports\emp.xml
      DESTYPE=file desname=emp.pdf DESFORMAT=pdf
      SERVER=server_name

When you use `rwrun`, the Reports Runtime command, the equivalent command line would be:

    rwrun USERID=username/password@my_db
      REPORT=c:\corp\myreports\emp.xml
      DESTYPE=file DESNAME=emp.pdf DESFORMAT=PDF

When you run an XML report definition in this way, you must specify an XML file extension. You could also apply an XML customization file to this report using the `CUSTOMIZE` command line keyword.

### 16.4.3 Performing Batch Modifications

If you have a large number of reports that need to be updated, then you can use the `CUSTOMIZE` command line keyword with `rwconverter` to perform modifications in batch. Batch modifications are particularly useful when you must make a repetitive change to a large number of reports (for example, changing a field's format mask). Rather than opening each report and manually making the change in Reports Builder, you can run `rwconverter` once and make the same change to a large number of reports at once.

The following example applies two XML report definitions, `translate.xml` and `customize.xml`, to three RDF files, `inven1.rdf`, `inven2.rdf`, and `manu.rdf`, and saves the revised definitions to new files, `inven1_new.rdf`, `inven2_new.rdf`, and `manu_new.rdf`.

    rwconverter username/password@my_db
      STYPE=rdffile SOURCE="(inven1.rdf, inven2.rdf, manu.rdf)"
      DTYPE=rdffile DEST="(inven1_new.rdf, inven2_new.rdf, manu_new.rdf)"
      CUSTOMIZE="(d:\apps\trans\translate.xml,d:\apps\custom\customize.xml)"
      BATCH=yes

Note: In this example, the `CUSTOMIZE` value demonstrates a directory path to files stored on a Windows platform. For UNIX, use that platform's standard for specifying directory paths (that is, forward slashes instead of backward).

## 16.5 Debugging XML Report Definitions

The following features are available to help you debug your XML report files:

- XML Parser Error Messages

- Tracing Options

- rwbuilder

- Writing XML to a File for Debugging

### 16.5.1 XML Parser Error Messages

The XML parser is part of Oracle's XML Development Kit (XDK), which is delivered with the core Oracle Database release. The XML parser is a Java package that checks the validity of XML syntax. The JAR files that contain the XML parser are automatically set up on install and are available to Oracle Reports.

The XML parser catches most syntax errors and displays an error message. The error message contains the line number in the XML where the error occurred as well as a brief description of the problem.

For more information on the XML parser, see the Oracle Technology Network, (`http://www.oracle.com/technology/index.html`). Search for XML parser or XDK. Information is also available in the documentation that came with your Oracle Database.

### 16.5.2 Tracing Options

When testing your XML report definition, it can be useful to run your report along with additional options to create a trace file. For example:

    rwrun username/password@my_db REPORT=\CORP\MYREPORTS\EMP.XML
      TRACEFILE=emp.log TRACEMODE=trace_replace TRACEOPTS=trace_app

The last three options in this command line generate a trace file that provides a detailed listing of report processing. The default location for trace file logs is the same on Windows and UNIX platforms:

    ORACLE_HOME\reports\logs\

Note: In this example, the `REPORT` option and the path to the trace log demonstrate directory paths to files stored on a Windows platform. For UNIX, use that platform's standard for specifying directory paths,that is, forward slashes instead of backward.

### 16.5.3 rwbuilder

When designing an XML report definition, it is sometimes useful to open it in Reports Builder. In Reports Builder, you can quickly determine if the objects are being created or modified as expected. For example, if you are creating summaries in an XML report definition, then opening the definition in Reports Builder enables you to quickly determine if the summaries are being placed in the appropriate group in the data model.

To open a full report definition in Reports Builder, use the `REPORT` (or `MODULE`) keyword. For example:

    rwbuilder USERID=username/password@my_db REPORT=c:\corp\myreports\emp.xml

To open a partial report definition in Reports Builder, use the `CUSTOMIZE` keyword. For example:

    rwbuilder USERID=username/password@my_db REPORT=emp.rdf CUSTOMIZE=c:\myreports\emp.xml

Note: In this example, the `REPORT` option specifies a directory path to files stored on a Windows platform. For UNIX, use that platform's standard for specifying directory paths (that is, forward slashes instead of backward slashes).

In both cases, Reports Builder is opened with the XML report definition in effect. You can then use the various views of Reports Builder to determine if the report is being created or modified as you expected.

### 16.5.4 Writing XML to a File for Debugging

If you are using `SRW.ADD_DEFINTION` to build an XML report definition in memory, then it can be helpful to write the XML to a file for debugging purposes. The following example demonstrates a procedure that writes each line that you pass to it to the document buffer in memory and, optionally, to a file that you specify.

    PROCEDURE addaline (newline VARCHAR, outfile Text_IO.File_Type) IS
    BEGIN
      SRW.ADD_DEFINITION(newline);
      IF :WRITE_TO_FILE='Yes' THEN
        Text_IO.Put_Line(outfile, newline);
      END IF;
    END;

For this example to work, the PL/SQL that calls this procedure would need to declare a variable of type `TEXT_IO.File_Type`. For example:

    custom_summary  Text_IO.File_Type;

You would also need to open the file for writing and call the `addaline` procedure, passing it the string to be written and the file to which it should be written. For example:

    custom_summary := Text_IO.Fopen(:file_directory || 'vid_summ_per.xml', 'w');
    addaline('<report name="video_custom" author="Generated" DTDVersion="9.0.2.0.0">',
    custom_summary);