ToXmlDoc (Record function): Difference between revisions
m (→Examples) |
|||
(16 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{Template:Record:ToXmlDoc subtitle}} | {{Template:Record:ToXmlDoc subtitle}} | ||
<var>ToXmlDoc</var> has options to display in uppercase or lowercase, as well as | <var>ToXmlDoc</var> has options to display in uppercase or lowercase, as well as | ||
to output the values of | to output the values of a record's fields as XML attributes or as XML text | ||
of the field XML element. | of the field XML element. | ||
The record extraction performed by <var>ToXmlDoc</var> is the | The record extraction performed by <var>ToXmlDoc</var> is the | ||
same operation that is performed by the [[XmlDoc API]] methods <var>[[LoadFromRecord (XmlDoc/XmlNode subroutine)|LoadFromRecord]]</var> and <var>[[NewFromRecord (XmlDoc function)|NewFromRecord]]</var>, as is further described below in [[#Usage notes| | same operation that is performed by the [[XmlDoc API]] methods <var>[[LoadFromRecord (XmlDoc/XmlNode subroutine)|LoadFromRecord]]</var> and <var>[[NewFromRecord (XmlDoc function)|NewFromRecord]]</var>, as is further described below in [[#Usage notes|Usage notes]]. | ||
<var>ToXmlDoc</var> is available in <var class="product">Sirius Mods</var> version 7.3 and later. | <var>ToXmlDoc</var> is available in <var class="product">Sirius Mods</var> version 7.3 and later. | ||
==Syntax== | ==Syntax== | ||
{{Template:Record:ToXmlDoc syntax}} | {{Template:Record:ToXmlDoc syntax}} | ||
===Syntax terms=== | ===Syntax terms=== | ||
<table class="syntaxTable"> | <table class="syntaxTable"> | ||
Line 15: | Line 17: | ||
<td>An <var>XmlDoc</var> object variable to contain the record data. | <td>An <var>XmlDoc</var> object variable to contain the record data. | ||
</td></tr> | </td></tr> | ||
<tr><th>record</th> | <tr><th>record</th> | ||
<td>An instantiated <var>Record</var> object variable. | <td>An instantiated <var>Record</var> object variable. | ||
</td></tr> | </td></tr> | ||
<tr><th><var>AttributeValues</var></th> | <tr><th><var>AttributeValues</var></th> | ||
<td>This [[ | <td>This [[Notation conventions for methods#Named parameters|name required]] argument is a <var>[[Enumerations#Using Boolean enumerations|Boolean]]</var> value that indicates whether a field value will be displayed as XML text or as an XML attribute (belonging to its field, which is displayed as an <var>XmlDoc</var> element). | ||
For example, <code><APSUBUND>COMM</APSUBUND></code> is text format, and <code><APSUBUND value="COMM"/></code> is attribute value format. | For example, <code><APSUBUND>COMM</APSUBUND></code> is text format, and <code><APSUBUND value="COMM"/></code> is attribute value format. | ||
The default value is <var>False</var>, which produces text format. | The default value is <var>False</var>, which produces text format.</td></tr> | ||
</td></tr> | |||
<tr><th><var>AttributeNames</var></th> | <tr><th><var>AttributeNames</var></th> | ||
<td>This name required argument | <td>This name required argument is a <var>Boolean</var> value that indicates whether field names are to be displayed within their XML document elements as the element name or as the value of a "name" attribute. | ||
For example, <code><APSUBUND>COMM</APSUBUND></code> is element-name format, and the following is name-as-attribute format: <p class="code"> <field name="APSUBUND"> COMM </field> </p> | For example, <code><APSUBUND>COMM</APSUBUND></code> is element-name format, and the following is name-as-attribute format: | ||
<p class="code"><field name="APSUBUND"> COMM </field> | |||
</p> | |||
The default value as of <var class="product">Sirius Mods</var> version 7.6 (and maintenance back to version 7.3) is <var>True</var>, which produces name-as-attribute format. Formerly, the default value was <var>False</var>. | The default value as of <var class="product">Sirius Mods</var> version 7.6 (and maintenance back to version 7.3) is <var>True</var>, which produces name-as-attribute format. Formerly, the default value was <var>False</var>. | ||
The name-as-attribute format from the <var>True</var> option is better suited to operations on the <var>XmlDoc</var>, particularly a record copying operation. The element-name format from the <var>False</var> option is useful for displaying field names that are not valid as XML element names (for example, names with embedded spaces). | The name-as-attribute format from the <var>True</var> option is better suited to operations on the <var>XmlDoc</var>, particularly a record copying operation. The element-name format from the <var>False</var> option is useful for displaying field names that are not valid as XML element names (for example, names with embedded spaces). | ||
For more information about handling non-valid XML names, see "Usage Notes," below. | For more information about handling non-valid XML names, see "Usage Notes," below.</td></tr> | ||
</td></tr> | |||
<tr><th><var>NamesToLower</var></th> | <tr><th><var>NamesToLower</var></th> | ||
<td>This name required argument | <td>This name required argument is a <var>Boolean</var> value that indicates whether field name data is to be displayed in lowercase characters. The default value is <var>False</var>, which produces uppercase output.</td></tr> | ||
</td></tr> | |||
<tr><th><var>AllowUnreversible</var></th> | <tr><th><var>AllowUnreversible</var></th> | ||
<td>This name required argument | <td>This name required argument is a <var>Boolean</var> value that indicates whether a request is cancelled if a field name would be changed irreversibly by lowercasing or by replacing with a period the characters that would be invalid in an XML document. | ||
For example, as described below in "Usage Notes," fields FOO BAR and FOO%BAR would both produce the element name <code>FOO.BAR</code> if AttributeNames is set to <code>False</code>. This will cause request cancellation unless AllowUnreversible is set to <code>True</code>. | For example, as described below in "Usage Notes," fields <code>FOO BAR</code> and <code>FOO%BAR</code> would both produce the element name <code>FOO.BAR</code> if <var>AttributeNames</var> is set to <code>False</code>. This will cause request cancellation unless <var>AllowUnreversible</var> is set to <code>True</code>. | ||
The default value is <var>False</var>, which allows request cancellation to alert you about unreversible field names. | The default value is <var>False</var>, which allows request cancellation to alert you about unreversible field names.</td></tr> | ||
</td></tr> | |||
<tr><th><var>CodepageTable</var></th> | <tr><th><var>CodepageTable</var></th> | ||
<td>This name required argument is a <var>Boolean</var> value; if <var>True</var>, the translations defined by the '''base''' Unicode codepage are used when translating from EBCDIC to Unicode for storing in the <var>XmlDoc</var>. | <td>This name required argument is a <var>Boolean</var> value; if <var>True</var>, the translations defined by the '''base''' Unicode codepage are used when translating from EBCDIC to Unicode for storing in the <var>XmlDoc</var>. | ||
Line 47: | Line 52: | ||
The advantage of using <code>CodepageTable=False</code> is that it will allow you to readily modify the <var>XmlDoc</var> directly (that is, with the <var>[[AddElement (XmlDoc/XmlNode function)|AddElement]]</var> and <var>[[AddAttribute (XmlNode function)|AddAttribute]]</var> methods). Those operations will use the standard Unicode translation tables; there is no way to perform them using the base codepage translation tables. | The advantage of using <code>CodepageTable=False</code> is that it will allow you to readily modify the <var>XmlDoc</var> directly (that is, with the <var>[[AddElement (XmlDoc/XmlNode function)|AddElement]]</var> and <var>[[AddAttribute (XmlNode function)|AddAttribute]]</var> methods). Those operations will use the standard Unicode translation tables; there is no way to perform them using the base codepage translation tables. | ||
<p><var>CodepageTable</var> is available as of <var class="product">Sirius Mods</var> version 7.6.</p> </td></tr> | <p><var>CodepageTable</var> is available as of <var class="product">Sirius Mods</var> version 7.6.</p> </td></tr> | ||
<tr><th><var>Base64Encode</var></th> | |||
<td>This name required argument is a <var>Boolean</var> value. | |||
<p>The default is <var>True</var>, which indicates that before storing a field's value in the <var>XmlDoc</var>, the value is base64 encoded <b>if needed</b>. See the [[#casEnc|usage note]] below that describes the conditions that would require base64 encoding.</p> | |||
<p> | |||
If <var>Base64Encode</var> value is <var>False</var>, field values are not base64 encoded. This means: </p> | |||
<ul> | |||
<li>Control and uninvertible characters are translated to their Unicode counterparts. | |||
<li>X'00' (if the <var>AllowNull</var> argument is not <var>True</var>) and untranslatable characters can cause request cancellation, unless they are mapped by the <var>CharacterMap</var> argument. (An unmapped untranslatable character actually throws a <var>[[CharacterTranslationException class|CharacterTranslationException]]</var> exception, which results in cancellation if not caught.) | |||
</ul> | |||
<p> | |||
<var>Base64Encode</var> is available as of <var class="product">Model 204</var> version 7.5.</p> </td></tr> | |||
<tr><th><var>CharacterMap</var></th> | |||
<td>This name required argument is a <var>[[CharacterToUnicodeMap class|CharacterToUnicodeMap]]</var> value. If a non-null value is provided, then the specified map is used to translate non-<var>UTF8</var>/<var>16</var> field values from EBCDIC to Unicode before storing in the <var>XmlDoc</var>. | |||
<p>Also, if a non-null value is provided, then the <var>Base64Encode</var> argument is forced to the value <var>True</var>, and the processing indicated by that is performed.</p> | |||
<p><var>CharacterMap</var> is available as of <var class="product">Model 204</var> version 7.5.</p> </td></tr> | |||
<tr><th><var>AllowNull</var></th> | <tr><th><var>AllowNull</var></th> | ||
<td>The value of this name required <var>Boolean</var> argument, which defaults to <var>False</var>, is copied to the <var>[[AllowNull (XmlDoc property)|AllowNull]]</var> property of the <var>XmlDoc</var> created by <var>ToXmlDoc</var>. The <var>XmlDoc</var>'s <var>AllowNull</var> property, in turn, determines whether field values that contain the X'00' character are stored in the <var>XmlDoc</var> with base64 encoding. Such values are base64 encoded if the <var>AllowNull</var> property is <var>False</var> (the default). For an example, see [[#Handling records with null characters|Handling records with null characters]] in the <var>[[NewFromRecord (XmlDoc function)|NewFromRecord]]</var> method description. | |||
<td>The value of this name required <var>Boolean</var> argument, which defaults to <var>False</var>, is copied to the <var>[[AllowNull (XmlDoc property)|AllowNull]]</var> property of the <var>XmlDoc</var> created by <var>ToXmlDoc</var>. The <var>XmlDoc</var>'s <var>AllowNull</var> property, in turn, determines whether field values that contain the X'00' character are stored in the <var>XmlDoc</var> with base64 encoding. Such values are base64 encoded if the <var>AllowNull</var> property is <var>False</var> (the default). For an example, see [[#Handling records with null characters| | <p><var>AllowNull</var> is available as of <var class="product">Sirius Mods</var> version 7.7.</p> | ||
<p><var>AllowNull</var> is available as of <var class="product">Sirius Mods</var> version 7.7.</p> | |||
</td></tr> | </td></tr> | ||
</table> | </table> | ||
Line 66: | Line 87: | ||
subtree to a non-empty <var>XmlDoc</var>; | subtree to a non-empty <var>XmlDoc</var>; | ||
in other cases the <var>NewFromRecord</var> virtual constructor may be your choice. | in other cases the <var>NewFromRecord</var> virtual constructor may be your choice. | ||
<p> | <p> | ||
Since <var>NewFromRecord</var> and <var>ToXmlDoc</var> create new <var>XmlDoc</var> objects, they have the | Since <var>NewFromRecord</var> and <var>ToXmlDoc</var> create new <var>XmlDoc</var> objects, they have the | ||
<var>AllowNull</var> argument for setting the created <var>XmlDoc</var>'s <var>[[allowNull (XmlDoc property)|AllowNull]]</var> | <var>AllowNull</var> argument for setting the created <var>XmlDoc</var>'s <var>[[allowNull (XmlDoc property)|AllowNull]]</var> | ||
poperty; <var>LoadFromRecord</var> does not have the <var>AllowNull</var> argument.</p> | poperty; <var>LoadFromRecord</var> does not have the <var>AllowNull</var> argument.</p> | ||
<p> | <p> | ||
As stated, both | As stated, both | ||
<var>NewFromRecord</var> and <var>LoadFromRecord</var> must be | <var>NewFromRecord</var> and <var>LoadFromRecord</var> must be | ||
contained in a record loop, for example, an <var>FRN</var> block, and they may not be | contained in a record loop, for example, an <var>FRN</var> block, and they may not be | ||
invoked within a fieldgroup context.</p> | invoked within a fieldgroup context.</p> | ||
<p> | <p> | ||
Except for these considerations, <var>ToXmlDoc</var>, <var>NewFromRecord</var>, and <var>LoadFromRecord</var> | Except for these considerations, <var>ToXmlDoc</var>, <var>NewFromRecord</var>, and <var>LoadFromRecord</var> | ||
all perform the same operation and have the same arguments. | all perform the same operation and have the same arguments. | ||
</p> | </p> | ||
<div id="othusage"></div> | <div id="othusage"></div> | ||
<li>If any fields have name characters that are not valid when displayed | <li>If any fields have name characters that are not valid when displayed | ||
Line 84: | Line 106: | ||
name is formatted as an attribute value, | name is formatted as an attribute value, | ||
the <var>ToXmlDoc</var> method converts the problematic characters to periods. | the <var>ToXmlDoc</var> method converts the problematic characters to periods. | ||
<p> | |||
For example, if field <code>FOO BAR</code> has value <code>XXX</code>, | For example, if field <code>FOO BAR</code> has value <code>XXX</code>, | ||
the <var>AttributeNames</var> parameter value is <code>False</code>, and the <var>NamesToLower</var> | the <var>AttributeNames</var> parameter value is <code>False</code>, and the <var>NamesToLower</var> | ||
and <var>AttributeValues</var> parameters are set to <code>True</code>, the resulting display | and <var>AttributeValues</var> parameters are set to <code>True</code>, the resulting display | ||
would be: | would be: </p> | ||
<p class="code"> <foo.bar value="XXX"> | <p class="code"> <foo.bar value="XXX"> | ||
</p> | </p> | ||
<li>If <var>NamesToLower</var> is set to <code>True</code>, any field name containing lowercase | <li>If <var>NamesToLower</var> is set to <code>True</code>, any field name containing lowercase | ||
characters is considered unreversible; reversing would involve converting the | characters is considered unreversible; reversing would involve converting the | ||
Line 96: | Line 119: | ||
To avoid request cancellation because of this, you must set to <code>True</code> | To avoid request cancellation because of this, you must set to <code>True</code> | ||
the <var>AllowUnreversible</var> parameter. | the <var>AllowUnreversible</var> parameter. | ||
<li> | |||
<li>In versions of <var class="product">Model 204</var> prior to 7.5, the effect of the <var>Base64Encoding</var>=<var>False</var> argument can be accomplished by post-processing the <var>XmlDoc</var> and replacing values which have an <code>encoding="base64"</code> attribute with the base64 decoded value translated to Unicode. | |||
is | |||
<li>UTF8 and UTF16 fields are copied directly to the <var>XmlDoc</var>; there is no translation (either automatic or using | |||
the <var>CharacterMap</var> argument) nor base64 encoding involved for them. | |||
<li>The <var>Base64Encode</var>=<var>False</var> argument can be used to disable any base64 encoding of field values. | |||
< | |||
</ | |||
Alternatively, the <var>CharacterMap</var> argument (with a non-null value) can be used to disable any base64 encoding of field values, and to specify translations, which can avoid request cancellation due to X'00' and/or untranslatable characters in field values. | |||
<div id="casEnc"></div> | |||
<li>If the <var>Base64Encode</var> argument is <var>False</var> (the default), and | |||
a non-UTF8/16 field value contains certain characters, the <var>ToXmlDoc</var> output | |||
data is automatically base64 encoded, and an attribute called <code>encoding</code> | |||
is added to the field's XML element with a value of <code>base64</code>. | |||
The cases that result in base64 encoding are: | |||
<ul> | |||
<li>The null character (X'00'), unless the <var>XmlDoc</var> has <var>AllowNull</var>=<var>True</var> | |||
<li>Any other non-displayable character, that is, the X'01' .. X'3F' control characters | |||
<li>A character that is not translatable to Unicode | |||
<li>A character <i>e</i> that translates to some Unicode character <i>u</i>, but the Unicode character | |||
<i>u</i> does not translate to <i>e</i> | |||
</ul> | |||
To exemplify these cases, | |||
consider this request based on some cleverly constructed records | |||
(although it uses <var>LoadFromRecord</var>, the output <var>XmlDoc</var> | |||
would be the same using <var>ToXmlDoc</var>): | |||
<p class="code"><nowiki>* Uses X'AD' as EBCDIC left square bracket (U+005B): | |||
UNICODE table standard base codepage 1047 | |||
* Not a good idea, but for this example, also use X'BA' as left square bracket: | |||
UNICODE table standard trans e=ba to u=005b | |||
b | |||
%doc is object xmlDoc | |||
for 5 records | |||
printText {~=$curRec} {~=(FOO):stringToHex} | |||
%doc = new | |||
%doc:loadFromRecord | |||
%doc:print | |||
skip 1 line | |||
end for | |||
frn 0 | |||
print '** Finally try null character again, this time with XmlDoc AllowNull=True: **' | |||
printText {~=$curRec} {~=(FOO):stringToHex} | |||
%doc = new | |||
%doc:allowNull = true | |||
%doc:loadFromRecord | |||
%doc:print | |||
end for | |||
end | |||
</nowiki></p> | |||
The output (again, with the records setup for this example) of the above request is: | |||
<p class="output"><nowiki>$curRec=0 (FOO):stringToHex=00 | |||
<Record version="1" file="QAWORK" number="0"> | |||
<field name="COMMENT"> | |||
Null character causes base64, unless AllowNull=True | |||
</field> | |||
<field name="FOO" encoding="base64"> | |||
AA== | |||
</field> | |||
</Record> | |||
$curRec=1 (FOO):stringToHex=01 | |||
<Record version="1" file="QAWORK" number="1"> | |||
<field name="COMMENT"> | |||
Control character causes base64 | |||
</field> | |||
<field name="FOO" encoding="base64"> | |||
AQ== | |||
</field> | |||
</Record> | |||
$curRec=2 (FOO):stringToHex=FF | |||
<Record version="1" file="QAWORK" number="2"> | |||
<field name="COMMENT"> | |||
Untranslatable character causes base64 | |||
</field> | |||
<field name="FOO" encoding="base64"> | |||
/w== | |||
</field> | |||
</Record> | |||
$curRec=3 (FOO):stringToHex=BA | |||
<Record version="1" file="QAWORK" number="3"> | |||
<field name="COMMENT"> | |||
Uninvertible translation causes base64 | |||
</field> | |||
<field name="FOO" encoding="base64"> | |||
ug== | |||
</field> | |||
</Record> | |||
$curRec=4 (FOO):stringToHex=AD | |||
<Record version="1" file="QAWORK" number="4"> | |||
<field name="COMMENT"> | |||
Invertible translation does *not* cause base64 | |||
</field> | |||
<field name="FOO"> | |||
[ | |||
</field> | |||
</Record> | |||
** Finally try null character again, this time with XmlDoc AllowNull=True: ** | |||
$curRec=0 (FOO):stringToHex=00 | |||
<Record version="1" file="QAWORK" number="0"> | |||
<field name="COMMENT"> | |||
Null character causes base64, unless AllowNull=True | |||
</field> | |||
<field name="FOO"> | |||
� | |||
</field> | |||
</Record> | |||
</nowiki></p> | |||
<li>The <var>ToXmlDoc</var> method will copy all fields, except those the user does not have access to due to field level security. Note that the <var>AddToRecord</var> method, which allows you to copy a record extracted by <var>ToXmlDoc</var> into another record, may not add all of the copied fields. | <li>The <var>ToXmlDoc</var> method will copy all fields, except those the user does not have access to due to field level security. Note that the <var>AddToRecord</var> method, which allows you to copy a record extracted by <var>ToXmlDoc</var> into another record, may not add all of the copied fields. | ||
<li>The <var>ToXmlDoc</var> method will add BLOB values to the output | <li>The <var>ToXmlDoc</var> method will add BLOB values to the output | ||
<var>XmlDoc</var>, no matter how large they are. | <var>XmlDoc</var>, no matter how large they are. | ||
Line 136: | Line 246: | ||
The <var>ToXmlDoc</var> method insists that the <var>Record</var> object be locked at least in | The <var>ToXmlDoc</var> method insists that the <var>Record</var> object be locked at least in | ||
share mode, therefore it gets no locks while it operates. | share mode, therefore it gets no locks while it operates. | ||
No locks are required for a sorted record or in single-user mode. | No locks are required for a sorted record or in single-user mode. | ||
See [[#Getting record lock| | See [[#Getting record lock|Getting record lock]] below for an example of obtaining a share record lock when processing an unlocked found set. | ||
</ul> | </ul> | ||
==Examples== | ==Examples== | ||
In addition to the example in the following section, see the [[NewFromRecord (XmlDoc function)#Handling records with null characters| | In addition to the example in the following section, see the [[NewFromRecord (XmlDoc function)#Handling records with null characters|Handling records with null characters]] example in the <var>NewFromRecord</var> article, which applies equally to <var>ToXmlDoc</var>. | ||
===AttributeValues, AttributeNames, and NamesToLower arguments=== | ====AttributeValues, AttributeNames, and NamesToLower arguments==== | ||
The display of field data below is produced | The display of field data below is produced | ||
by the following request: | by the following request: | ||
Line 161: | Line 271: | ||
The following are sample results: | The following are sample results: | ||
<p class="code"> <Record file="CCASYS" number="1"> | <p class="code"><Record file="CCASYS" number="1"> | ||
<field name="APSURTYP"> | |||
SDEF | |||
</field> | |||
<field name="APSUNM"> | |||
SUBSYSMGMT | |||
</field> | |||
<field name="APSUBUND"> | |||
COMM | |||
</field> | |||
<field name="APSUERRC"> | |||
ERROR | |||
</field> | |||
... | ... | ||
<Record file="CCASYS" number="1"> | |||
<field name="apsurtyp"> | |||
SDEF | |||
</field> | |||
<field name="apsunm"> | |||
SUBSYSMGMT | |||
</field> | |||
<field name="apsubund"> | |||
COMM | |||
</field> | |||
<field name="apsuerrc"> | |||
ERROR | |||
</field> | |||
... | ... | ||
<Record file="CCASYS" number="1"> | |||
<field name="APSURTYP" value="SDEF"/> | |||
<field name="APSUNM" value="SUBSYSMGMT"/> | |||
<field name="APSUBUND" value="COMM"/> | |||
<field name="APSUERRC" value="ERROR"/> | |||
... | ... | ||
<Record file="CCASYS" number="1"> | |||
<apsurtyp value="SDEF"/> | |||
<apsunm value="SUBSYSMGMT"/> | |||
<apsubund value="COMM"/> | |||
<apsuerrc value="ERROR"/> | |||
... | ... | ||
</p> | </p> | ||
===Getting record lock=== | |||
As stated in the [[#othusage| | ====Getting record lock==== | ||
<p class="code" | As stated in the [[#othusage|Usage notes]] above, a record lock of at least <var>Share</var> strength is required for the record processed by <var>ToXmlDoc</var>. If you are processing an unlocked record set, you can use the <var>[[LoopLockStrength (Recordset property)|LoopLockStrength]]</var> property so that for each iteration of a <var>For Each Record</var> loop using the recordset, the current record is locked, as shown in the following example: | ||
<p class="code">%recSet is object recordset in QAWORK | |||
* In this fragment, %rec is null, only used to qualify the currentRecord constructor | |||
%rec is object record in QAWORK | %rec is object record in QAWORK | ||
find without locks all records to %recSet | find without locks all records to %recSet | ||
Line 215: | Line 326: | ||
... | ... | ||
end for | end for | ||
</p> | |||
Since the <var>LoadFromRecord</var> and <var>NewFromRecord</var> methods do not have a <var>Record</var> method object, using them in the above loop would be either <code>%doc:loadFromRecord</code> or <code>%doc = newFromRecord</code>, respectively (and in this fragment the <code>%rec</code> variable would not be needed). | Since the <var>LoadFromRecord</var> and <var>NewFromRecord</var> methods do not have a <var>Record</var> method object, using them in the above loop would be either <code>%doc:loadFromRecord</code> or <code>%doc = newFromRecord</code>, respectively (and in this fragment the <code>%rec</code> variable would not be needed). | ||
==See also== | ==See also== | ||
{{Template:Record:ToXmlDoc footer}} | {{Template:Record:ToXmlDoc footer}} |
Latest revision as of 20:48, 31 July 2014
Return in an XmlDoc the fields and values of the Record object's record (Record class)
[Requires Janus SOAP]
ToXmlDoc has options to display in uppercase or lowercase, as well as to output the values of a record's fields as XML attributes or as XML text of the field XML element.
The record extraction performed by ToXmlDoc is the same operation that is performed by the XmlDoc API methods LoadFromRecord and NewFromRecord, as is further described below in Usage notes.
ToXmlDoc is available in Sirius Mods version 7.3 and later.
Syntax
%doc = record:ToXmlDoc[( [AttributeValues= boolean], - [AttributeNames= boolean], [NamesToLower= boolean], - [AllowUnreversible= boolean], - [CodepageTable= boolean], [Base64Encode= boolean], - [CharacterMap= characterToUnicodeMap], - [AllowNull= boolean])] Throws CharacterTranslationException
Syntax terms
%doc | An XmlDoc object variable to contain the record data. |
---|---|
record | An instantiated Record object variable. |
AttributeValues | This name required argument is a Boolean value that indicates whether a field value will be displayed as XML text or as an XML attribute (belonging to its field, which is displayed as an XmlDoc element).
For example, |
AttributeNames | This name required argument is a Boolean value that indicates whether field names are to be displayed within their XML document elements as the element name or as the value of a "name" attribute.
For example, <field name="APSUBUND"> COMM </field> The default value as of Sirius Mods version 7.6 (and maintenance back to version 7.3) is True, which produces name-as-attribute format. Formerly, the default value was False. The name-as-attribute format from the True option is better suited to operations on the XmlDoc, particularly a record copying operation. The element-name format from the False option is useful for displaying field names that are not valid as XML element names (for example, names with embedded spaces). For more information about handling non-valid XML names, see "Usage Notes," below. |
NamesToLower | This name required argument is a Boolean value that indicates whether field name data is to be displayed in lowercase characters. The default value is False, which produces uppercase output. |
AllowUnreversible | This name required argument is a Boolean value that indicates whether a request is cancelled if a field name would be changed irreversibly by lowercasing or by replacing with a period the characters that would be invalid in an XML document.
For example, as described below in "Usage Notes," fields |
CodepageTable | This name required argument is a Boolean value; if True, the translations defined by the base Unicode codepage are used when translating from EBCDIC to Unicode for storing in the XmlDoc.
This argument is for the unusual case where you anticipate that the XML document is to be used later by AddToRecord, and the standard Unicode translation tables in place when AddToRecord is invoked may differ from those in place when the record was copied to the XmlDoc. The default value is False, which uses the standard Unicode translation tables, including any modifications specified in CodepageTable is available as of Sirius Mods version 7.6. |
Base64Encode | This name required argument is a Boolean value.
The default is True, which indicates that before storing a field's value in the XmlDoc, the value is base64 encoded if needed. See the usage note below that describes the conditions that would require base64 encoding. If Base64Encode value is False, field values are not base64 encoded. This means:
Base64Encode is available as of Model 204 version 7.5. |
CharacterMap | This name required argument is a CharacterToUnicodeMap value. If a non-null value is provided, then the specified map is used to translate non-UTF8/16 field values from EBCDIC to Unicode before storing in the XmlDoc.
Also, if a non-null value is provided, then the Base64Encode argument is forced to the value True, and the processing indicated by that is performed. CharacterMap is available as of Model 204 version 7.5. |
AllowNull | The value of this name required Boolean argument, which defaults to False, is copied to the AllowNull property of the XmlDoc created by ToXmlDoc. The XmlDoc's AllowNull property, in turn, determines whether field values that contain the X'00' character are stored in the XmlDoc with base64 encoding. Such values are base64 encoded if the AllowNull property is False (the default). For an example, see Handling records with null characters in the NewFromRecord method description.
AllowNull is available as of Sirius Mods version 7.7. |
Usage notes
- Whether to use ToXmlDoc, NewFromRecord, or LoadFromRecord depends on what is
most convenient for your application.
If you are already using a Record object which references the desired record,
using ToXmlDoc may be more convenient; if not, then either
LoadFromRecord or NewFromRecord (both of which require that the method be
contained in a record loop, for example, For Each Record) may be more convenient.
You must use LoadFromRecord if you want to add the record's content as a
subtree to a non-empty XmlDoc;
in other cases the NewFromRecord virtual constructor may be your choice.
Since NewFromRecord and ToXmlDoc create new XmlDoc objects, they have the AllowNull argument for setting the created XmlDoc's AllowNull poperty; LoadFromRecord does not have the AllowNull argument.
As stated, both NewFromRecord and LoadFromRecord must be contained in a record loop, for example, an FRN block, and they may not be invoked within a fieldgroup context.
Except for these considerations, ToXmlDoc, NewFromRecord, and LoadFromRecord all perform the same operation and have the same arguments.
- If any fields have name characters that are not valid when displayed
as an XML element name, or if they have characters that are non-displayable when the
name is formatted as an attribute value,
the ToXmlDoc method converts the problematic characters to periods.
For example, if field
FOO BAR
has valueXXX
, the AttributeNames parameter value isFalse
, and the NamesToLower and AttributeValues parameters are set toTrue
, the resulting display would be:<foo.bar value="XXX">
- If NamesToLower is set to
True
, any field name containing lowercase characters is considered unreversible; reversing would involve converting the names to uppercase. To avoid request cancellation because of this, you must set toTrue
the AllowUnreversible parameter. - In versions of Model 204 prior to 7.5, the effect of the Base64Encoding=False argument can be accomplished by post-processing the XmlDoc and replacing values which have an
encoding="base64"
attribute with the base64 decoded value translated to Unicode. - UTF8 and UTF16 fields are copied directly to the XmlDoc; there is no translation (either automatic or using the CharacterMap argument) nor base64 encoding involved for them.
- The Base64Encode=False argument can be used to disable any base64 encoding of field values. Alternatively, the CharacterMap argument (with a non-null value) can be used to disable any base64 encoding of field values, and to specify translations, which can avoid request cancellation due to X'00' and/or untranslatable characters in field values.
- If the Base64Encode argument is False (the default), and
a non-UTF8/16 field value contains certain characters, the ToXmlDoc output
data is automatically base64 encoded, and an attribute called
encoding
is added to the field's XML element with a value ofbase64
. The cases that result in base64 encoding are:- The null character (X'00'), unless the XmlDoc has AllowNull=True
- Any other non-displayable character, that is, the X'01' .. X'3F' control characters
- A character that is not translatable to Unicode
- A character e that translates to some Unicode character u, but the Unicode character u does not translate to e
To exemplify these cases, consider this request based on some cleverly constructed records (although it uses LoadFromRecord, the output XmlDoc would be the same using ToXmlDoc):
* Uses X'AD' as EBCDIC left square bracket (U+005B): UNICODE table standard base codepage 1047 * Not a good idea, but for this example, also use X'BA' as left square bracket: UNICODE table standard trans e=ba to u=005b b %doc is object xmlDoc for 5 records printText {~=$curRec} {~=(FOO):stringToHex} %doc = new %doc:loadFromRecord %doc:print skip 1 line end for frn 0 print '** Finally try null character again, this time with XmlDoc AllowNull=True: **' printText {~=$curRec} {~=(FOO):stringToHex} %doc = new %doc:allowNull = true %doc:loadFromRecord %doc:print end for end
The output (again, with the records setup for this example) of the above request is:
$curRec=0 (FOO):stringToHex=00 <Record version="1" file="QAWORK" number="0"> <field name="COMMENT"> Null character causes base64, unless AllowNull=True </field> <field name="FOO" encoding="base64"> AA== </field> </Record> $curRec=1 (FOO):stringToHex=01 <Record version="1" file="QAWORK" number="1"> <field name="COMMENT"> Control character causes base64 </field> <field name="FOO" encoding="base64"> AQ== </field> </Record> $curRec=2 (FOO):stringToHex=FF <Record version="1" file="QAWORK" number="2"> <field name="COMMENT"> Untranslatable character causes base64 </field> <field name="FOO" encoding="base64"> /w== </field> </Record> $curRec=3 (FOO):stringToHex=BA <Record version="1" file="QAWORK" number="3"> <field name="COMMENT"> Uninvertible translation causes base64 </field> <field name="FOO" encoding="base64"> ug== </field> </Record> $curRec=4 (FOO):stringToHex=AD <Record version="1" file="QAWORK" number="4"> <field name="COMMENT"> Invertible translation does *not* cause base64 </field> <field name="FOO"> [ </field> </Record> ** Finally try null character again, this time with XmlDoc AllowNull=True: ** $curRec=0 (FOO):stringToHex=00 <Record version="1" file="QAWORK" number="0"> <field name="COMMENT"> Null character causes base64, unless AllowNull=True </field> <field name="FOO"> � </field> </Record>
- The ToXmlDoc method will copy all fields, except those the user does not have access to due to field level security. Note that the AddToRecord method, which allows you to copy a record extracted by ToXmlDoc into another record, may not add all of the copied fields.
- The ToXmlDoc method will add BLOB values to the output
XmlDoc, no matter how large they are.
A BLOB field will have
a
reserved
attribute added to the field element if more bytes were reserved in the BLOB than are in the actual value. - Typically, before they proceed, PAI, AppendFieldValues, and other operations that extract field names and values automatically get a share lock on a record if it appears to be unlocked. The ToXmlDoc method insists that the Record object be locked at least in share mode, therefore it gets no locks while it operates. No locks are required for a sorted record or in single-user mode. See Getting record lock below for an example of obtaining a share record lock when processing an unlocked found set.
Examples
In addition to the example in the following section, see the Handling records with null characters example in the NewFromRecord article, which applies equally to ToXmlDoc.
AttributeValues, AttributeNames, and NamesToLower arguments
The display of field data below is produced by the following request:
OPENC FILE CCASYS b %r is object record in file ccasys %r = new(1) %r:toXmlDoc:print %r:toXmlDoc(namesToLower=true):print %r:toXmlDoc(attributeValues=true):print %r:toXmlDoc(attributeValues=true, attributeNames=false, - namestoLower=true):print end
The following are sample results:
<Record file="CCASYS" number="1"> <field name="APSURTYP"> SDEF </field> <field name="APSUNM"> SUBSYSMGMT </field> <field name="APSUBUND"> COMM </field> <field name="APSUERRC"> ERROR </field> ... <Record file="CCASYS" number="1"> <field name="apsurtyp"> SDEF </field> <field name="apsunm"> SUBSYSMGMT </field> <field name="apsubund"> COMM </field> <field name="apsuerrc"> ERROR </field> ... <Record file="CCASYS" number="1"> <field name="APSURTYP" value="SDEF"/> <field name="APSUNM" value="SUBSYSMGMT"/> <field name="APSUBUND" value="COMM"/> <field name="APSUERRC" value="ERROR"/> ... <Record file="CCASYS" number="1"> <apsurtyp value="SDEF"/> <apsunm value="SUBSYSMGMT"/> <apsubund value="COMM"/> <apsuerrc value="ERROR"/> ...
Getting record lock
As stated in the Usage notes above, a record lock of at least Share strength is required for the record processed by ToXmlDoc. If you are processing an unlocked record set, you can use the LoopLockStrength property so that for each iteration of a For Each Record loop using the recordset, the current record is locked, as shown in the following example:
%recSet is object recordset in QAWORK * In this fragment, %rec is null, only used to qualify the currentRecord constructor %rec is object record in QAWORK find without locks all records to %recSet end find %recSet:loopLockStrength = share for each record in %recset ... %doc = %rec:currentRecord:toXmlDoc ... end for
Since the LoadFromRecord and NewFromRecord methods do not have a Record method object, using them in the above loop would be either %doc:loadFromRecord
or %doc = newFromRecord
, respectively (and in this fragment the %rec
variable would not be needed).