Generate object from %XML.Reader's Next method
Hi!
I have an issue when trying to generate an object when reading an XML file. All files I'll mention will be attached to this post as a PDF file, but it's really a ZIP one.
The XML file is used as a template to generate a PDF report through the JasperSoft Report API. I checked the file consistency, and it's all right. We are able to generate the PDF file with no issues. What we need to with Caché, is to read the XML file, correlate it to an object, so we can change properties from this file. The JasperSoft Studio and API capabilities are kinda lacking in a specific way, this is why we need to modify it from a default template, to a custom one, at runtime. The problem is that this is not a “basic” XML file, it contains two different XML Schemas, and two namespaces within it, so I guess that this is where my problem lies so far.
The idea is, in short:
Jasper Default JRXML template file → Load it in Caché → I modify some properties based on our internal needs → save the custom template → send it to the API to generate the report → delete the custom template.
I created two functions to illustrate what I'm able to do so far, and what my issue really is.
;
#include %occSAX
;
; Teste Table
;
; set sc=$$TesteTable^%CSWREPORTRG001()
TesteTable() ;
new sc,band,file,flg,i,object,reader,schemaComp,schemaRoot,status
;
kill reader
;
set file="C:\_jasper\basicTemplate.jrxml"
;
set reader=##class(%XML.Reader).%New()
set reader.SSLConfiguration=("SSLPadraoCSW")
set reader.SAXFlags=$$$SAXVALIDATIONSCHEMAFULLCHECKING
;
set schemaComp="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd"
set schemaRoot="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
Set reader.SAXSchemaSpec=schemaRoot_","_schemaComp
;
set status=reader.OpenFile(file)
;
w !,"status | "_$System.Status.DisplayError(status) ,!
;
do reader.Correlate("jasperReport","br.com.consistem.comp.jasper.jasperReport.v01.jasperReport")
do reader.Next(.object,.status)
;
w !,"status | "_$System.Status.DisplayError(status) ,!
;
zw object
;
set i=0,flg=0
for {
try {
set band=object.detail.band.GetAt(i).height
} catch {
set flg=$increment(flg)
set band=""
}
;
write !,"band "_band_" | cont "_i
;
quit:flg=2
set i=$increment(i)
}
;
quit 1
;
; Teste No Table
;
; set sc=$$TesteNoTable^%CSWREPORTRG001()
TesteNoTable() ;
new sc,band,file,flg,i,object,reader,status
;
kill reader
;
set file="C:\_jasper\basicTemplate_NoTable.jrxml"
;
set reader=##class(%XML.Reader).%New()
set reader.SSLConfiguration=("SSLPadraoCSW")
;
set status=reader.OpenFile(file)
;
w !,"status | "_$System.Status.DisplayError(status) ,!
;
do reader.CorrelateRoot("br.com.consistem.comp.jasper.jasperReport.v01.jasperReport")
do reader.Next(.object,.status)
;
w !,"status | "_$System.Status.DisplayError(status) ,!
;
zw object
;
set i=0,flg=0
for {
try {
set band=object.detail.band.GetAt(i).height
} catch {
set flg=$increment(flg)
set band=""
}
;
write !,"band "_band_" | cont "_i
;
quit:flg=2
set i=$increment(i)
}
;
quit 1
First, what I'm able to do. As you can see, in the TesteNoTable() function, I get to read the basicTemplate_NoTable.jrxml file and generate an object from the .Next method. I'm using the SSLConfiguration property, so you would do in order for it to work. When the code gets to the for loop, it is able to read the band height property set on the XML file.
As you can see in the images above, the XML file has two bands with height set to 65, and I'm able to create an object and read it.
Now, what I can't. When reading a different XML file, which contains another XML Schema within, and a different namespace set to it, I'm unable to get to the same properties from the object.
The file contains a table element, which requires another XML Scheme set to it.
Initially, using the same code to read it, I get an error when using the OpenFile method. I figured I need the $$$SAXVALIDATIONSCHEMAFULLCHECKING flag set to the SAXFlags property of the $XML.Reader object. After this, I can open the file, but then I'm unable to get to the table's properties, or even get the same properties I got when loading the simpler XML file. I also specified the Schemas related to this file on the SAXSchemaSpec property, to no success.
I tried multiple configurations for the Correlate method regarding the namespace and classes it uses, then set different flags to the reader object based in this document, to no luck.
Please, let me know if anyone was able to Correlate this correctly and get an object from an XML file this complex.