· Feb 12, 2022

Encoding XML carriage return / line feed


I'm using  %XML.Writer to write XML files from a database source, and I see that it is not encoding carriage return or line feed as 
 respectively, and is instead leaving them unencode.

What can I do to have them encoded?


Product version: IRIS 2020.1
$ZV: IRIS for Windows (x86-64) 2020.1 (Build 215U) Mon Mar 30 2020 20:14:33 EDT
Discussion (3)1
Log in or sign up to continue

Yes, I can see that might help. I'm writing the following class to XML

Class OutputData Extends (%Persistent, %XML.Adaptor)
Parameter XMLNAME = "OutputData"; 
Property Notes As %String(MAXLEN = "", XMLNAME = "Notes", XMLPROJECTION = "ATTRIBUTE");

Using the following code

#dim item as DATAEXTRACTION.Datix.Message.Fragment.NewClass1 
set item = ##class(DATAEXTRACTION.Datix.Message.Fragment.NewClass1).%New()
set item.Notes = "< > &" _$c(10)_$c(13)_ "TEST" 

#dim tWriter as %XML.Writer
set tWriter=##class(%XML.Writer).%New()
set tWriter.Indent=4 
do tWriter.OutputToFile("E:\Testing\out.xml") 
set tSC=tWriter.RootObject(item)

Which produces the following XML, the $C(10) and $C(13) are not encoded, but the other characters are:

<?xml version="1.0" encoding="UTF-8"?>
<OutputData Notes="&lt; &gt; &amp;


And what I want is:

<?xml version="1.0" encoding="UTF-8"?>
<OutputData Notes="&lt; &gt; &amp; &#xA; &#XD; TEST"></OutputData>

The reason for wanting this is that I'm building a new system to replace some legacy code and the data outputted by the new system has to be identical

Just checked XML spec and there's nothing about escaping $c(10) or $c(13).

The only symbols which must be escaped are:

  • " &quot;
  • & &amp;
  • ‘ &apos;
  • ' &apos;
  • < &lt;
  • > &gt;

You can check $zcvt - it produces the same output:

zw $zcvt("< > &" _$c(10)_$c(13)_ "TEST", "O", "XML")

If you need byte for byte compatibility you'll need a custom datatype with a redefined LogicalToXSD method. Something like:

Class test.XMLString Extends %String

ClassMethod LogicalToXSD(%val As %String) As %String [ CodeMode = objectgenerator, ServerOnly = 1 ]
    quit:%mode'="propertymethod" $$$OK
    Do %code.WriteLine($c(9) _ "set %val = $zcvt(%val,""O"",""XML"")")
    For replace=$lb("$c(10)","""&#xA"""),$lb("$c(13)","""&#xD""") {
        Set from = $lg(replace, 1)
        Set to = $lg(replace, 2)
        Do %code.WriteLine($c(9) _ "set %val = $replace(%val," _ from _ ", " _ to _")")
    Do %code.WriteLine($c(9) _ "quit %val")
    Quit $$$OK