Você está na página 1de 13

Reporting Extensibility

Feature Overview: Reporting Extensibility


Author: Lisa Slater Nicholls, Milind Lele, Richard Stanton Date: 1 April 2006

Table of Contents 1 Overview and Scope 1.1 Introduction 1.2 Goals 1.3 Non-goals 2 Scenarios 2.1 Specifying a Report Expression in different colors by value range
2.1.1 Test Scenario 2.1.2 Extension Scenarios

2 2 2 3 3 3
3 4

2.2 Adding and Using Document Properties


2.2.1 Test Scenario 2.2.2 Extension Scenario

4
4 5

2.3 Providing hyperlinks and anchors in HTML documents


2.3.1 Test Scenarios 2.3.2 Extension Scenario

5
5 5

2.4 Getting simultaneous dynamic print and HTML output


2.4.1 Test Scenario

5
5

2.5 Providing Graphing/custom Control behavior


2.5.1 Extension Scenario

5
5

3 Functional Description 3.1 Underlying Product Enhancements


3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 CallAdjustObjectSize CallEvaluateContents SET("REPORTBEHAVIOR") values from 91 to 99 ReportListener.PrintCachedPages() usability improvement PrintCachedPages() method ReportListener.CommandClauses.File value to be read-write in LoadReport

6 6
6 6 7 7 7

4 Xbase Extension Features 4.1 Enhancement to shipping preview: Expose PrintCachedPages() 4.2 Enhancements to shipping ReportBuilder and its exposed (FFC) utility classes
4.2.1 Dynamics tab for Report Expressions Properties dialog 4.2.2 Various Properties dialogs get HTML tab 4.2.3 _FRXCURSOR class to expose memberdata cursor handling

9 9 9
9 9 9

4.3 Enhancement to Report Output Application and FFC output classes


4.3.1 4.3.2 4.3.3 4.3.4 _ReportListener (FFC Xbase baseclass) support Appropriate FFC ReportListener.VCX revisions and additions Related VFP-RDL Schema revisions HTML XSLT revisions

10
10 10 11 13

Microsoft Corporation

Reporting Extensibility

1 Overview and Scope


1.1 Introduction
VFP 9.0 radically changed the Visual FoxPro Reporting System, and introduced a complex partnership between product and Xbase components to design and generate output. In Sedna, we propose to readdress certain aspects of this partnership that will improve users' ability to extend the reach and complexity of its Xbase side. Response to the original set of VFP 9 Reporting System features has been gratifying, and VFP users are graduating from their initial use of the improved base set to creating their own extensions. The FFC (FoxPro Foundation) classes provided in 9.0, which provide the default mechanism for generating all supported output types, do not leverage all these features. Doing so in VFP 9 would have imposed a performance penalty on all reports for gain that almost none would initially appreciate, since no old reports took advantage of them. As users become more familiar with the object-assisted abilities of the VFP Reporting System, they expect functionality more similar to what they have in VFP forms and controls, such as dynamic changes to text styles. While appropriate techniques were addressed as helpfile code examples in 9.0, it is now time to expose them directly in the default FFC classes. Providing this functionality has no direct analog in "old-style" VFP Reporting, and is not directly supported in the FRX (report metadata) format. For this reason, it was not included in the specified feature set of the shipping 9.0 ReportBuilder Xbase application, which has the job of writing to the FRX format during report design sessions. However, the VFP 9.0 Memberdata schema supports extensions to the reporting metadata for this and similar purposes. In Sedna, the ReportBuilder will expose Reporting Memberdata more thoroughly, so that run-time reporting extensions have the extra information it needs. Its method for doing so will also expose the basic ReportBuilder extensibility architecture as a model for additional added features and extensions to be contributed by third-party vendors and the FoxPro community. In general, the VFP 9.0 Reporting System was essentially a version 1.0 release, albeit an unusually complete one. In Sedna, we should round out the feature set for enhanced output elements and the supported alternative output formats where possible, laying the ground work for others to extend it in the future.

1.2 Goals
The following is a list of broad goals. Add minimal product enhancements to allow performance tuning when dynamic Xbase code is, and is not, being used Provide FFC core class code to expose and leverage these enhancements Extend the FFC-supplied Xbase output types (various XML-related output file types) to use dynamic behavior appropriately Add backward-compatible enhancements to VFP-RDL (report definition XML schema) to encourage both the dynamic behavior we supply and permit unspecified additional extensions Expose Reporting Memberdata format through dynamic runtime enhancements and through ReportBuilder extensions Expose ReportBuilder extensibility mechanisms

Microsoft Corporation

Reporting Extensibility

1.3 Non-goals
The following is a list of explicit non- goals. Explicit ReportBuilder UI for emulation of any/all specific Class Designer capabilities. IE, "DynamicFontBold", "DynamicFontItalic", etc properties will not be mimicked exactly, although it should be clear that this is possible given what we provide. Explicit demonstration of all implications of the FFC and VFP-RDL improvements. For example, while we provide the architecture for GDI+-handling report decoration objects, we may not include graph-rendering classes exploiting this architecture. While we provide the dynamic underpinning for use of the ReportListener's AdjustObjectSize method for the creation of custom controls, we may not supply such a custom control (see below for use case scenario). Creation of alternative Report Preview Container interfaces. The shipping Preview Container has been designed to replace the original VFP Preview facility with an Xbase look- and workalike. While many alternatives are possible, it is clear that the community is comfortable with this task and does not need much of a boost. We will add one enhancement to expose a small product improvement (see feature reference below) without which printing from Xbase preview is missing one print-from-preview capability of the original interface. This specification does not cover any alternative Preview UI suggestions that may be provided as examples showing up to use interop features to preview and print VFP reports using non-Xbase code.

Scenarios

Many of the scenarios below have two parts. The first section addresses one or more test scenarios expected to be available from in-the-box, delivered components. The second section addresses extension scenarios, which can be addressed by a tester, community member, or vendor adding components given the techniques demonstrated in-the-box.

2.1 Specifying a Report Expression in different colors by value range


2.1.1 Test Scenario
Mary has a report showing inventory levels. Each row of data, describing an inventory item, includes a target inventory level as well as the current quantity in inventory. She would like the current quantity expression to display in red when it falls below the target quantity, blue when it matches the target quantity, and orange when it exceeds twice the target quantity. Mary doubleclicks the Report Expression element representing current quantity in the report layout, and selects the Style tab in the Properties dialog. She unchecks the default use default pen color and the ellipsis button providing an opportunity to select an alternative color is enabled. She selects blue. [NB: So far, this is standard VFP 9.0 capability] Now she clicks the Dynamics tab. She sees a list of Conditions on the left. Currently there is one item in the list, labeled "Default". On the right she sees an example of what her text appears like with default formatting, similar to what she saw as a sample on the Style page. There are buttons to Add, Edit, and Delete conditions, and a Preview Script button. When she presses Add, a modal dialog provides ability to edit the dynamically-tunable aspects of the output expression, and a logical Condition, similar to the Print Only When Expression is True control available on the Print When tab. Because this is a new condition, initial values for each tunable item in this dialog are loaded to match the default set for this Report Expression. For example, the Forecolor (Pen) value is initially blue, and the Text item reads "Inventory.CurrentLevel". When she has finished creating her condition and selecting the items to change, she presses OK in this dialog. She is prompted to create a label for the new condition. The label is validated for uniqueness (within this list of conditions for this object; it does not have to be unique across objects). Upon return

Microsoft Corporation

Reporting Extensibility

to the Properties dialog, the Dynamics tab now shows two conditions on the left. When she selects each of them, she sees the difference in the sample on the right. If she is not editing in PROTECTED (end-user) mode, and presses Preview Script, she sees a generated version of the script that will run. The generated script includes a comment for each condition, to identify it with her user-label. Should she or another viewer wish to edit the script directly, they can do so, by using the Run-time extensions feature from the Other dialog tab. They can paste the generated preview version in, if desired. Note: If a non-PROTECTED user moves his or her conditions into explicit script, generally s/he will want to delete them from the conditions list. However it does no harm, except slight performance detriment, to leave the extra CASE statements in. See next note below. When she confirms her changes by pressing OK to dismiss the Properties dialog, the Dynamics Tab saves her changes as XML records in the metadata for this layout control, using a specified reserved name attribute for these records. Note: Explicit script in the reserved first metadata row, with empty name attribute, can be executed along with the Dynamics tab generated script. Dynamics tab-generated script executes last. This gives the end-user last-say in making these cosmetic changes.

2.1.2 Extension Scenarios


Mary is delivering an application in which a report may be edited by end users in PROTECTED mode. For some objects, she wants no dynamic behavior beyond what she has specified, so the entire Dynamics tab should be unavailable for those Report Expressions. Mary subclasses Dynamics tab to evaluate an object's Protection settings, and act accordingly. She replaces the class name for this tab in ReportBuilder registry, in the delivered version of her application. Michelle creates an add-on that rotates text by degrees or percent. She implements this as a GFX extension object (see: Xbase Extension features, FXListener, below). She provides her own user interface for her add-ons as a separate ReportBuilder Tab. Michelle's add-ons may store their information in the User field as value-pairs, or in separate metadata records, with a name attribute value she publishes. She declares her design-time interface class in the ReportBuilder registry, and she indicates the requirement to load her GFX object in the ReportListener registry table. The GFX object receives information about the dynamicallyenhanced text, consults its own instructions and successfully rotates the result. Michelle makes her class available to Mary, and documents her class's required run-time instruction format. Mary can choose to include Michelle's ReportBuilder UI extension tab or adjust her own subclass of the Dynamics tab to write Michelle's rotational instructions.

2.2 Adding and Using Document Properties


2.2.1 Test Scenario
James wishes to record a Keywords property to a report. He right-clicks on an empty region of his report layout and selects Properties from the context menu to display the Report Properties dialog. He selects the Document tab. James enters a value of Sales Department, Product Catalog, 2002 for the Keywords entry. (Note that this is an expression and therefore string values are required the quotes. James could enter the name of a Report Variable or a UDF() here.) James also includes an entry for Document Title along with Keywords. Note that we will use a subset of items from Word's Document Properties dialog Summary tab for the entries here. There is potential for a Custom extension here, similar to Word's Document Properties' Custom tab. This would be a modal dialog box allowing Add, Edit, Delete. James can provide the Name of his new Document attribute and enter an expression to be evaluated for it in this dialog.

Microsoft Corporation

Reporting Extensibility

When James creates HTML output from this report, the underlying XML document contains an appropriate item including the keywords in its <Run/> section, forced to a string version of the evaluated expression. The resulting HTML document contains this information in its <HEAD/> element. The <Run/> section will also contain a Title node, so the HTML document uses this information in place of its defaults. If James uses NOPAGEEJECT to chain multiple reports into a single HTML document, and if he designates keyword expressions for each, multiple sets of keywords are generated in the document <HEAD/> element. The <TITLE/> node for the compound document, like the printer page information and other aspects of the chained run, is extrapolated from the first report in the set.

2.2.2 Extension Scenario


A new output type (PDF or DOC) can leverage the provided document properties, using one of two methods (through XML or direct). It can also add new ones (new tab, new metadata name value).

2.3 Providing hyperlinks and anchors in HTML documents


Layout control (and also probably minimal version for bands) gets HTML tab in Properties dialog.

2.3.1 Test Scenarios


two HTML documents, one with links, one with anchors images get non-default ALT attribute contents layout elements get TITLE attributes

2.3.2 Extension Scenario


RSS: RSS nodes include hyperlinks to reference anchors in HTML

2.4 Getting simultaneous dynamic print and HTML output


In Sedna dynamic content will work for Successors.

2.4.1 Test Scenario


Mary uses the report created in first scenario above. Instantiates a listener for Types 0 and 5, specifies the latter as a Successor to the former. LOCAL loX, loY STORE NULL TO loX, loY DO (_REPORTOUTPUT) WITH 0, loX DO (_REPORTOUTPUT) WITH 5, loY loX.Successor = loY REPORT FORM Inventory OBJECT loX Both print and HTML result should show color changes.

2.5 Providing Graphing/custom Control behavior


2.5.1 Extension Scenario
Extension: add Dynamics tab similar to Report Expressions for Image and Shape layout controls, but exposing different tunable attributes as appropriate to AdjustObjectSize. Add memberdata, use gfx or not.

Microsoft Corporation

Reporting Extensibility

Functional Description

3.1 Underlying Product Enhancements


Dynamic behavior in ReportListener class takes place in the EvaluateContents event for Report Expression layout controls, and in the AdjustObjectSize event for shape and image controls. The product currently looks for code in the Xbase class hierarchy for the object serving as ReportListener to evaluate whether it trigger these events, which pose a significant performance penalty and perform no native service in the product. In Sedna, two new properties will allow an Xbase class to indicate whether it needs each of the two events to be triggered, whether there is code in the class tree for each event or not.

3.1.1 CallAdjustObjectSize
Integer property, description: Indicates whether ReportListener should invoke AdjustObjectSize for all appropriate layout controls. If a user sets any value than the defined values below, an error will occur (existing error number that seems appropriate: 1469, property value is out of bounds).

Value 0 (default) 1 2

Result VFP 9.0 behavior: event triggered for all layout controls if there is code in the Xbase class hierarchy for this event. Do not trigger event, whether or not there is code; dynamic behavior in AdjustObjectSize is not desired or needed for this report run. Always trigger event, whether or not there is code. This value is primarily intended for users who expect to use BindEvents rather than code in the method, to ensure that behavior is not determined by whether or not there is code in the reportListener (since the developer of the bound object may not always know what reportListener class is being used). However it is also useful for helper objects involved in the reporting process to have this capability exposed to them.

The value of this property is interrogated by the baseclass ReportListener once, at the beginning of the report run, before the BeforeReport event. Note that, if the value is 1 or 2, the product does not need to do its 9.0 check, since these values take precedence. This is the same point at which the ReportListener currently checks for user code in AdjustObjectSize part of its FRX-loading process; the evaluation will not change from whenever it's currently done. See additional notes on behavior and usage in CallEvaluateContents section below.

3.1.2 CallEvaluateContents
See CallAdjustObjectSize above works exactly the same way, but governs the use of EvaluateContents event instead of AdjustObjectSize. In addition to evaluation of these properties during the report initialization, we will investigate to see if the Engine can also obey the values of these two properties after the start of the report. It will probably be possible to change the values of CallAdjustObjectSize and CallEvaluateContents in the BeforeBand event, meaning for all layout controls in a single band. This will allow for significant optimization, even for reports that require some dynamic behavior. For example, reports with layout rectangles in page headers, detail bands, and page footers might have one rectangle in a group header band serving as a placeholder for a gdiplus-rendered summary graph. Only the group header band needs CallAdjustObjectSize = .T.. Similarly, a report expression in a page header band might have font alterations for some types of presentations, but all the other

Microsoft Corporation

Reporting Extensibility

bands might have a very large number of report expressions not requiring any EvaluateContents adjustments. In these cases, user code can adjust the CallAdjustObjectSize and CallEvaluateContents properties on a band level, at will. It will not be recommended, and it is probably not feasible, for user code to attempt to finetune performance by turning these properties on and off for individual objects rather than between bands. Especially with AdjustObjectSize, it is difficult to predict in what order, or even how many times, these events occur with respect to other layout controls of the same type within a given band. Also there is no reasonable place/event to do this evaluation and change the property values for each layout control, before AdjustObjectSize and EvaluateContents are actually called for this same layout control. Adding such an event (complete with frxRecNo information to tie it together with the appropriate layout control) would not only be risky but also reduce any runtime performance benefit.

3.1.3 SET("REPORTBEHAVIOR") values from 91 to 99


The SET REPORTBEHAVIOR command will allow values from 91 - 99 without error, and will behave as though value is 90 if any of these values are used. Currently, values lower than 80 and higher than 90 produce an error. SET("REPORTBEHAVIOR") will returns exact value (for example 95) specified by the user. Note that the values between 81 - 89 already work this way: engine uses SET REPORTBEHAVIOR 80 behavior and SET("REPORTBEHAVIOR") returns exact value specified by the user: set reportbehavior 85 ? set("REPORTBEHAVIOR")

3.1.4 ReportListener.PrintCachedPages() usability improvement PrintCachedPages() method


Method signature: no args, no significant return value. Description: Provides the ability to print cached pages after a report run with ListenerType 1 or 3. This method allows a user to request the product to print cached pages without ending the preview experience. Currently, the only way to do this is to call ReportListener.OnPreviewClose(lPrint). Similar to OnPreviewClose, this method will be aware of the relevant ReportListener.Commandclauses members (Prompt, PrintPageCurrent, PrintRangeFrom, and PrintRangeTo). Internally, this should be accomplished by splitting up the work currently done when OnPreviewClose is called into two parts, so the printing behavior should be absolutely consistent.

3.1.5 ReportListener.CommandClauses.File value to be read-write in LoadReport


ReportListener.CommandClauses exists to provide user code with knowledge of the conditions and clauses used on the current REPORT FORM command. By design, native code fills, but does not read or use, CommandClauses member properties for a report run, except in specified circumstances. As an example of a specified circumstance, user code can make a change to ReportListener.CommandClauses.Prompt and this change is respected when ReportListener.PrintCachedPages() or ReportListener.OnPreviewClose(.T.) is called. The read-write special cases are documented in the CommandClauses help file topic. In VFP 9 RTM and SP1, ReportListener.CommandClauses.File is not one of the specified exceptions. In Sedna, native code will read the new value of ReportListener.CommandClauses.File after LoadReport, which is the point at which native code reads the FRX and begins to process it. The value in this property, not the original value in the REPORT FORM command, will determine what FRX the native code reads and processes.

Microsoft Corporation

Reporting Extensibility

This change enables user code to preprocess the FRX in a multi-user-safe way, by making a private copy of the FRX and instructing the engine to use this copy for the current run. Xbase code can create a temporary FRX copy and (for example) remove objects not needed for the current OutputType value or other conditions, such as permissions levels to various kinds of content. Although it is possible to do similar things using events during the report run, this change provides better performance for changes that affect every instance of a layout control in a report run (or remove it altogether, or is a global change of any other type, such as a change to DataEnvironment items). It is also possible to do the same thing (preprocess the FRX table, creating a temporary copy)before issuing the REPORT FORM command, but this approach does not "bind" the preprocessing behavior into the ReportListener system. Making this change allows the FFC listeners to add a preprocessing hook with some built-in intelligence. If the new value is unusable (named file cannot be found, is not a valid FRX, is open in another Designer session or locked by another user for some other reason, etc), the same or similar errors will be thrown as if the REPORT FORM command was issued with an unusable filename originally. Test code: LPARAMETERS WhichTest #DEFINE OtherReport "c:\temp\some.frx" #DEFINE ThisReport "c:\temp\other.frx" CLEAR TRY ox = CREATEOBJECT("r") DO CASE CASE EMPTY(WhichTest) USE (OtherReport) EXCLU CASE WhichTest = 1 MODI REPO (OtherReport) NOWAIT OTHERWISE * we will be setting to non-existant report name ox.fileNotExist = .T. ENDCASE REPORT FORM (ThisReport) object ox CATCH TO err LIST OBJECTS LIKE err MESSAGEBOX(MESSAGE() + " " + MESSAGE(1)) ENDTRY CLEAR ALL CLOSE ALL RETURN DEFINE CLASS r as ReportListener listenertype = 1 fileNotExist = .F. PROCEDURE loadreport IF THIS.fileNotExist THIS.CommandClauses.File = "somethingsomething.frx" ELSE THIS.CommandClauses.File = OtherReport ENDIF ENDPROC ENDDEFINE

From the ReportListener's Xbase code point of view, along with being able to "see" this error in a surrounding TRY-CATCH, the end result is similar to what happens if the Xbase code issues a RETURN .F. from the LoadReport method: no report run occurs. Since this result is already a possibility, it should be handled in the surrounding user code. For example, if the report run is

Microsoft Corporation

Reporting Extensibility

supposed to create a file, it is already a valid possibility that the output target file will not exist after the run. As usual, user code that makes such a change accepts responsibility to make it safely, not remove items critical to report calculations, clean up any temporary files afterwards, etc. We will recommend that CommandClauses.File be restored by user code to contain the same value it would have contained normally in UnloadReport. This user action does not require any response or adjustment in native code, but it allows any followup user code reading the value after the report run to see the correct value. Note that pre-processing the FRX under design during a Report Designer run is not possible in exactly the same way. Because the Report Designer has a lock on the CommandClauses.File FRX or LBX, user code can't make a copy of it easily. (By design, the ReportListener is passed the actual FRX or LBX value, not the temporary FRX or LBX name, during a Design session. We will not change this in Sedna.) We will recommend that Xbase code check ReportDesigner.CommandClauses.IsDesignerLoaded to determine what is possible. In some circumstances, it is possible for user code to compensate for this scenario transparently. In others, user code may have to indicate the unavailability of a certain feature during the designer session. We will provide at least one object illustrating appropriate behavior. Note that, during Designer sessions, if there is a tightly-coupled Builder and Output application pair, it is probably feasible for the Builder to hook the Preview event, create a copy of the FRX on disk in a temporary file with a generated name, and place the fully-pathed name of the copy someplace that the ReportListener-derived class can find it (such as a _* public variable). The ReportListener could then adjust this "safe" copy and pass the name of the copy to the Engine in CommandClauses.File during LoadReport. We will not supply any objects that rely on this technique.

Xbase Extension Features

4.1 Enhancement to shipping preview: Expose PrintCachedPages()


The print button in the previews that ship with VFP will default to not close preview after printing. This is consistent with print preview behavior in other Microsoft tools. Other existing, third party, previews will continue to work as before (close preview after printing) since the old API will continue to work.

4.2 Enhancements to shipping ReportBuilder and its exposed (FFC) utility classes
4.2.1 Dynamics tab for Report Expressions Properties dialog
Other dynamically tunable aspects, beyond font color, of Report Expressions will also be available from this dialog (optimally, all properties that are readwrite in the EvaluateContents event).

4.2.2 Various Properties dialogs get HTML tab


See third scenario above. Reference HTML Listener XSLT enhancements below.

4.2.3 _FRXCURSOR class to expose memberdata cursor handling


Required for dynamic work by practically everybody, and the Builder is already doing much of what everybody is going to need.

Microsoft Corporation

Reporting Extensibility

4.3 Enhancement to Report Output Application and FFC output classes


This section uses the terms "base set of dynamic attributes" and "supported set of dynamic attributes". The word "attributes" (either type) refers both to dynamic report or report control behavior, as it is generated by user code, and also to the expression of this code in report output. Please note the following definitions. As used in this document, "base set of dynamic attributes" refers to control attributes that can be altered during EvaluateContents and AdjustObjectSize code. These intrinsically exist on a product level, and we will now expose them in FFC Xbase code. "Supported set of dynamic attributes" refers to this base set plus any other dynamic attributes for which we include Xbase code in-the-box. "Extended" or "user-driven dynamic attributes", while not discussed here, are also possible. These represent additional behavior not intrinsically provided by the FRX format or the base product, or by in-the-box

4.3.1 _ReportListener (FFC Xbase baseclass) support


_ReportListener will now include code to call Successors during dynamic methods. At the start of a report run, it will poll Successors for appropriate CallEvaluateContents and CallAdjustObjectSize values to evaluate these values.

4.3.2 Appropriate FFC ReportListener.VCX revisions and additions


FXListener supporting FX and GFX decorator collections will be included in hierarchy, descending from _ReportListener. FXListener will poll its collections for additional input into CallEvaluateContents and CallAdjustObjectSize final values. FX and GFX decoration capabilities exist only when FXListener functions as the lead listener, they are ignored in Successors. Only the lead has the ability to communicate directly with the engine for the purposes of tuning EvaluateContents and AdjustObjectSize calls, and it also makes sense to do all decoration up-front, before generating additional forms of output. (This strategy is already recommended and illustrated in the docs. Practical scenario in fourth scenario above.) Thus, polling of the FX and GFX collections for CallEvaluateContents and CallAdjustObjectSize also only is done by the lead. FXListener will replace UpdateListener as default listener supplied for ListenerType 0 (print) and 1 (preview) activities. This exchange will permit Successor chain behavior such as specified in fourth scenario above. FXListener will supply properties allowing users to nominate a feedback class, class library, and container module as the appropriate decorator object for feedback during a report run. FXTherm object supplying same feedback behavior as UpdateListener will be the reference implementation. Note that UpdateListener will continue to exist in the classlibrary and that, if improvements are made to FXTherm's behavior over UpdateListener's behavior, these improvements are easily ported back. We will maintain them in tandem. This is important to ensure that people who are using UpdateListener explicitly shouldn't lose out on any improvements. Also, people who (for any reason) want user feedback to come from a Successor rather than the lead listener will be able to use UpdateListener for this purpose. UtilityReportListener will descend from FXListener rather than directly from _ReportListener. UtilityReportListener supplies file handling and the ability to read and manage a configuration table, so it is the class from which all supported Xbase extension output types (Debug, XML, etc) descend. As a result, decoration capabilities are available in all these classes (HTMLListener will have the ability to create the color changes described in fourth scenario when it is not a Successor as well, IOW.) XMLListener and its descendents (XMLDisplayListener and HTMLListener) will have access to dynamically-altered attributes and will expose any supported base set of dynamic attributes in output. Descendent classes may also support dynamic attributes specific to their form of output. For example,

Microsoft Corporation

10

Reporting Extensibility

HTMLListener can support an expression that should be evaluated to provide the name of a CSS class attribute, and will almost certainly support the addition of expressions to supply href and title attributes on those layout controls that can use them. XMLListener will provide a mechanism to generate new optional Run section of the VFP-RDL (see below). Descendent classes will have the necessary ability to alter and embellish the contents of this section. For example, HTMLListener can add one or more Run child element to indicate desired reference(s) to external CSS stylesheets. XMLListener will also provide a mechanism to generate Memberdata-describing nodes in the VFPDataSet section of the VFP-RDL (see below). This will leverage the shared Memberdata-handling _FRXCURSOR.VCX object. The additional nodes will thus use the schema already provided in the current Memberdata documentation. By "exploding" the embedded Memberdata XML documents contained in rows of the FRX, and make it easier for consumers of the XML to use this information if desired. For example, an RSSListener will know what report elements are tagged for inclusion in the RSS output without directly parsing the memberdata.

4.3.3 Related VFP-RDL Schema revisions


Please see the Using VFP Report Output XML topic in the VFP 9 helpfile, which contains the VFP 9.0 VFP-RDL schema in full. In Sedna, VFP-RDL Schema will explicitly expose availability of base dynamic attributes, and will be somewhat revised for readability. Note that the schema revisions will not render 9.0 version documents invalid. Also note that the XSD will not include any non-base supported dynamic attributes; it already permits ANY attributes (using <xs:anyAttribute processContents="lax"/> ) to be added to various elements. VFP-RDL Schema will offer a new optional Run section making it possible to include additional userdriven dynamic attributes on a report level. (In 9.0, you can add object-level attributes, but there is no obvious place to add new attributes on a global level.) Excerpt from revised XSD, with new elements in green:

<xs:element name="VFP-Report"> <xs:annotation> <xs:documentation> Contents of VFP-Report element are determined by XMLListener.XMLMode property </xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element ref="VFP-RDL" minOccurs="0"/> <xs:element ref="Data" minOccurs="0"/> <xs:element ref="Run" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Run"> <xs:annotation> <xs:documentation> Allows runtime data-dependent document attributes, such as contents of report variables or other accumulated data elements that do not occur in the layout itself, to be added at the conclusion of a report run. Content type is set at xs:any deliberately to allow extensions such as cursor-shaped XML for rows, etc. </xs:documentation> </xs:annotation>

Microsoft Corporation

11

Reporting Extensibility

<xs:complexType mixed="true"> <xs:sequence maxOccurs="unbounded"> <xs:element name="property" type="VFP-Property"/> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="VFP-Property" mixed="true"> <xs:sequence> <xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="id" type="xs:string" use="required"/> <xs:anyAttribute processContents="lax"/> </xs:complexType> We will demonstrate the use of this section by generating Run XML elements from whatever Document Properties and HTML global elements we expose in the supported set of document attributes. For example, document keywords or CSS style sheet references. The FRX-describing section of the VFP-RDL schema will be revised to include Memberdata information. Our VFP-RDL schema will now reference types defined in the VFP Memberdata Schema as an xs:include. See the Memberdata Extensibility topic, in the VFP docs, which contains this simple schema in full (we will not alter it in Sedna). Excerpt from revised VFP-RDL schema, with new element in green and its definition, derived directly from Memberdata schema, in red: <xs:element name="VFP-RDL"> <xs:complexType> <xs:sequence> <xs:element name="VFPDataSet" type="VFPDataSet"/> </xs:sequence> <xs:attribute name="id" type="xs:string" use="required"/> </xs:complexType> </xs:element> <xs:complexType name="VFPDataSet"> <xs:sequence> <xs:element name="VFPFRXLayoutObject" type="VFPFRXLayoutObject" minOccurs="1" maxOccurs="unbounded"/> <xs:element name="VFPFRXLayoutNode" type="VFPFRXLayoutNode" minOccurs="1" maxOccurs="unbounded"/> <xs:element name="VFPDataSource" type="VFPDataSource" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="VFPFRXCommand" type="VFPFRXCommand" minOccurs="0" maxOccurs="1"/> <xs:element name="VFPFRXPrintJob" type="VFPFRXPrintJob" minOccurs="0" maxOccurs="1"/> <xs:element name="VFPFRXMemberData" type="VFPFRXMemberData" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="VFPFRXMemberData"> <xs:annotation> <xs:documentation>Provides information contained in the FRX's embedded MemberData XML documents for various objects.</xs:documentation> </xs:annotation> <xs:attributeGroup ref="Common"/> <xs:attributeGroup ref="ReportTemplate"/> <xs:anyAttribute processContents="lax"/> </xs:complexType>

Microsoft Corporation

12

Reporting Extensibility

4.3.4 HTML XSLT revisions


The base XSLT supplied with HTMLListener will be aware of the full set of HTML-appropriate supported dynamic attributes. The base XSLT will also include abilities to recognize and leverage more HTML-appropriate attributes than we can expose in-the-box. This was already true in the VFP 9.0 version, but we will extend these abilities to as many HTML capabilities as seems feasible. As an example, the base XSLT recognized href attributes on Report Expression nodes and created appropriate HTML results if they existed. Although nothing in-the-box took advantage of this, adding href attributes into the source XML was (a) permitted by the VFP-RDL and (b) trivial to do in an HTMLListener subclass, according to whatever rules you chose to tag a Report Expression as a hyperlink. In Sedna, we may or may not support and standardize a method for generating href attributes. Either way, the XSLT will recognize href attributes on Picture layout controls as well as Report Expressions, since this is obviously desirable behavior.

Microsoft Corporation

13

Você também pode gostar