XMLListener is responsible for delivery of the VFP-RDL schema and, as such, changes in SP2 to include the generation of two new sets of nodes and several attributes that are optional inclusions in the VFP RDL SP2 schema.
The two new elements are
- VFPFRXMemberData, a section of the RDL metadata description section of the XML, which decodes memberdata from the MemberData alias
- Run, a section of the report run data section of the XML, which holds user-designated values that have been gathered over the life of the REPORT FORM command execution. This node is generated at the conclusion of the REPORT FORM run.
The new attributes for which XMLListener is primarily responsible are:
- dataTextAttr and dataTypeAttr, which optionally hold information gathered directly from the result of data expressions on elements representing text layout controls. This occurs before the Report Engine translates the contents of the expression to a string and applies formatting codes to the string, and is useful for sending the results of the run to a data-centric format such as Excel
- pageImageAttr, which holds the filename of the file generated as a pageimage on elements marked with the Advanced Property associating that layout element with a page image.
As a note regarding these schema extensions and future schema extensions of your own: XMLListener's derived classes can add attributes to element nodes because the schema designates layout elements' nodes as including <xs:anyAttribute processContents="lax"/>. Both XMLDisplayListener and HTMLListener take advantage of this opportunity.
Because attribute names are specified as configurable, derived classes adding attributes should be careful to follow the procedures used in the FFC class set to name and expose them. User code should also make their current names available to user XSLT transform if any are required and are not under your code's direct control, again following the model you see used to handle standard attributes.
Unlike the fully-configurable nature of attributes in the VFP-RDL schema, derived classes ordinarily cannot add new elements into the schema unless they import them from a separate namespace. There is one exception to this rule: the schema specifies the Run node as a sequence of VFP-Property elements that can include child-contents of any complex type. You can put any complex XML you want, of any design, into the default (VFP-RDL) namespace .
XMLListener takes advantage of the SP2 RunCollector feature to expose Document Property values in a fully-decoded fashion. The Run collection contains individual values for each Advanced Property row for the header record (the report's Document Properties). In Run, if the Document Property is of Expression type, the expression is evaluated and if it is of XML-String type, the value is unescaped and included as true XML child content. An illustration of this facility is included in this topic.
Tip |
---|
If you put any other contents into the RunCollector yourself, of course the XML
will contain values for them along with the DocumentProperties it includes by default.
XMLListener first checks your Run item value to see if it is an evaluatable expression;
if so, it uses the evaluated result of the expression. Otherwise, it includes the
value you provided without translation. You can use a cursor, an empty object, or a Collection-based object as your RunCollector member; XMLListener handles all three types in writing to the Run node. However, if XMLListener creates the RunCollector unilaterally, it creates the member as a Collection-based object. This scheme has distinct advantages for XML handling. Please see the comments in the PROTECTed method fillRunCollector for details. |
Caution |
---|
The RDL listing in the topic Using VFP Report Output XML appears to have been updated in the SP2 CHM but should not be relied on. The correct XSDs are delivered with the ReportOutput Application source in XSource. We will provide more information in TMM on this subject as well. |
A number of additional behind-the-scenes changes in this class occurred to make its XSLT parameters
more useful outside the reporting context, since VFP doesn't have any other
easy method for you to apply XSLT transforms to XML, and also more intelligent about
understanding potential charset scenarios within the reporting context. These
changes are referenced in remarks about specific properties and methods in the table
below.
The following table lists public properties and methods added by this class to its parent class, UtilityReportListener, and either omitted in the VFP SP2 CHM or requiring some additional comment.
Properties and methods | Description | ||
---|---|---|---|
adjustXSLTParameter Method |
Adds, changes, or removes a parameter in the XSLTParameters member
collection, creating the collection if necessary.
Syntax: adjustXSLTParameter( tvValue, tsKey[, tlRemoveOnly]) Return Values: logical Parameters: tvValue provides the value, of any type, of the parameter you wish to add or change in the collection. tsKey is the parameter name, case-sensitive, as it should be supplied to the XSLT transform. Note that if the parameter does not already exist, an XSLT accepts a new parameter transparently, so if you specify a parameter that does not already exist in the XSLT, this does not cause an error during the transformation process. If you pass tlRemoveOnly as .T., the parameter is removed from the collection if it is found. Remarks: The CHM HTMLListener topic includes an example of adding a parameter to the XSLTParameters collection, in two steps: (1) creating the collection member and (2) adding the parameter using the .Add method of the Collection base class. If you wanted to change the value of this parameter for a second report run, you would have to .Remove it first and then re-Add. You might also have had to iterate through the collection, first, before removing the original value, if you weren't sure whether it already existed or not. This custom method makes it possible to adjust the parameters collection without worrying about any of these details.
|
||
applyRDLTransform Property |
Default: .F. Remarks: This property is similar to applyUserTransform , indicating whether a transformation should be applied automatically at the conclusion of a report run. It applies when xmlMode=1 (RDL only) and the XSLTProcessRDL property is loaded.
|
||
applyXSLT Method |
Remarks: This existing method was revised in SP2 and received a new, option final paramter: m.tvFRXAlias. The changes to the method have following main goals:
Please see the comments in the method, and additional comments in the PROTECTED methods frxCharsetsInUse and fixMSXMLObjectForDTDs, for more information. |
||
dataTextAttr Property |
Supplies the name of the XML attribute used to show the TRANSFORM'd value of the evaluated expression for a field control layout object. Default: "DTEXT" |
||
dataTypeAttr Property |
Supplies the name of the XML attribute used to show the datatype of
the evaluated expression for a field control layout object. Default: "DTYPE" |
||
formattingChanges Property |
Reference in which classes can store information about actions taken to apply dynamic changes to layout controls' formatting attributes, for later use during Render event. Default: NULL Remarks: During a report run, this member holds the generated name of a cursor in the FRXDataSession, into which the values of the PROTECTed evaluateContentsValues empty object member are placed for reference by other participants in the run. Previous to SP2, this property originated in XMLDisplayListener, which derives from this class. |
||
includeDataTypeAttributes Property |
Indicates whether Data Type and Text information available in EvaluateContents should be included in the XML nodes generated for Field controls. Default: .F. Remarks: This feature is similar to the ones exposed by the includeFormattingInLayoutObjects property; it is turned off by default so you don't get XML attributes beyond a basic set unless you need them. It is exposed separately from the includeFormattingInLayoutObjects set of attributes because you will typically need the two sets on very different types of XML-related target output. |
||
pageImageAttr Property |
Supplies the name of the XML attribute used to show the filename for an associated generated page image file. Default: "PLINK" Remarks: See page image information in ReportListener Utility and File-handling Foundation Class, this class's parent. |
The following three Document Properties are defined for a report (each of a different type).
1. Document.Title = "My Doc Title " + TRANSF(DATETIME())<-- an expression
2. HTML.TextAreasOff = Yes <-- a boolean/logical
3. MyCustomDocPropertyOfXMLType = <root> <something> <other myattrib="test"> blah blah blah <more/> </other> </something> </root>
The Style record for the first record in the FRX looks like this:
<VFPData> <reportdata name="Microsoft.VFP.Reporting.Builder.AdvancedProperty" type="R" script=""
execute=""My Doc Title (an expr type)" + TRANS(DATETIME())"
execwhen="Document.Title" class="" classlib="" declass="1" declasslib=""
penrgb="" fillrgb="" pena="" filla="" fname="" fsize="" fstyle=""/> <reportdata name="Microsoft.VFP.Reporting.Builder.AdvancedProperty" type="R" script=""
execute="1" execwhen="HTML.TextAreasOff"
class="" classlib="" declass="5" declasslib=""
penrgb="" fillrgb="" pena="" filla="" fname="" fsize="" fstyle=""/> <reportdata name="Microsoft.VFP.Reporting.Builder.AdvancedProperty" type="R" script=""
execute="<root> <something> <other myattrib="test"> blah blah blah <more/> </other> </something> </root>" execwhen="MyCustomDocPropertyOfXMLType"
class="" classlib="" declass="2" declasslib=""
penrgb="" fillrgb="" pena="" filla="" fname="" fsize="" fstyle=""/> </VFPData>
The FRXCursor-produced Memberdata cursor rows for the report level (header record) look like this:
NAME EXECUTE EXECWHEN DECLASS ..Builder.AdvancedProperty "My Doc.. Document.Title 1 ..Builder.AdvancedProperty 1 HTML.TextAreasOff 5 ..Builder.AdvancedProperty <root>.. MyCustomDocPropertyOfXMLType 2
At runtime, they are available to XML in the FRXCursor-produced Memberdata cursor in the FRX session, looking the same as they do above, except that an FRXRECNO initial column has the value 1 for all three records, indicating that they belong to the header record.
At runtime, they are available in the XML output of XMLListener, first, as a STYLE column, completely escaped:
... <VFPDataSet> ... <VFPFRXLayoutObject> <frxrecno></frxrecno> <platform>WINDOWS&t;/platform> <name/> ... <fillpat>0</fillpat> <width>-1.000</width> <style> <VFPData> <reportdata name="Microsoft.VFP.Reporting.Builder.AdvancedProperty"
type="R" script="" execute="&quot;My Doc Title (an expr type)&quot; + TRANS(DATETIME())"
execwhen="HTML.Alt-Title" class="" classlib="" declass="1" declasslib=""
penrgb="" fillrgb="" pena="" filla="" fname="" fsize="" fstyle=""/> <reportdata name="Microsoft.VFP.Reporting.Builder.AdvancedProperty" type="R" script=""
execute="1" execwhen="HTML.PrintablePageLink" class="" classlib="" declass="5" declasslib=""
penrgb="" fillrgb="" pena="" filla="" fname="" fsize="" fstyle=""/> <reportdata name="Microsoft.VFP.Reporting.Builder.AdvancedProperty" type="R" script=""
execute="&lt;root&gt; &lt;something&gt; &lt;other myattrib=&quot;test&quot;&gt; blah blah blah &lt;more/&gt; &lt;/other&gt; &lt;/something&gt; &lt;/root&gt;" execwhen="MyCustomDocPropertyOfXMLType" class="" classlib="" declass="2"
declasslib="" penrgb="" fillrgb="" pena="" filla="" fname="" fsize="" fstyle=""/> </VFPData> </style> <picture/> </VFPFRXLayoutObject> ... </VFPDataSet> ...
At runtime they are also available as VFPFRXMemberData values, as three rows, looking just as they do in the Style record snapshot above, except with a VFPFRXMemberData parent tag and an extra element, frxrecno, with the value 1, indicating that they come from the header record:
... <VFPDataSet> ... <VFPFRXMemberData frxrecno="1"
name="Microsoft.VFP.Reporting.Builder.AdvancedProperty" type="R" script=""
execute=""My Doc Title (an expr type)" + TRANS(DATETIME())"
execwhen="Document.Title" class="" classlib="" declass="1" declasslib=""
penrgb="" fillrgb="" pena="" filla="" fname="" fsize="" fstyle=""/> <VFPFRXMemberData frxrecno="1"
name="Microsoft.VFP.Reporting.Builder.AdvancedProperty" type="R" script=""
execute="1" execwhen="HTML.TextAreasOff" class="" classlib="" declass="5" declasslib=""
penrgb="" fillrgb="" pena="" filla="" fname="" fsize="" fstyle=""/> <VFPFRXMemberData frxrecno="1"
name="Microsoft.VFP.Reporting.Builder.AdvancedProperty" type="R" script=""
execute="<root> <something> <other myattrib="test"> blah blah blah <more/> </other> </something> </root>" execwhen="MyCustomDocPropertyOfXMLType"
class="" classlib="" declass="2" declasslib=""
penrgb="" fillrgb="" pena="" filla="" fname="" fsize="" fstyle=""/> ... </VFPDataSet> ...
And, finally, at runtime, the same Document Property content is available fully decoded in the Run collection, along with any other information you may have put there during the run of the report:
... </Data>
<Run> <property id="Document.Title">My Doc Title 11/13/07 02:43:41 PM</property> <property id="HTML.TextAreasOff">1</property> <property id="MyCustomDocPropertyOfXMLType"> <root> <something> <other myattrib="test">
blah blah blah <more/> </other> </something> </root>
</property>
</Run>
</VFP-Report>
</Reports>
See Also