Xojo & Reporting with XML & XSL

I didn’t want to fully hi-jack a previous thread, but a side conversation became of it and figure I would move it into its own thread :slight_smile:

So the question from the previous reporting thread had to do with generating reports from Xojo while using the XML & XLS route to display the results. The one major advantage from using this method is that you keep your data separate from your report layout. If you wish to make changes to the placement of data, you can do so in the xsl file without much effort. :slight_smile:

This method also works great when you want to display a report within your application in which all you need to do is load it to an HTMLViewer. If you want to save the report or print the report, you can do so… but keep in mind that you would treat this as… “how can I do this in HTML” rather than… “how can I do this in Xojo.” The good news is, there are a number of resources out on the web to how to best format your HTML to have it display best when printing or saving.

Question from the other thread:

[quote=113436:@Richard Duke]another quick question. if i used the following code

Dim xml As New XmlDocument
  Dim root As XmlNode
  root = xml.AppendChild(xml.CreateElement("Artists"))
  Dim ArtistNode As XmlNode
  DIM rst AS RecordSet, mySQL as String, cnt as integer
  mySQL="SELECT * FROM tblArtist"
  rst = DoDBOpenRS(mySQL)
  if rst<>nil then
    While Not rst.eof
      cnt=cnt+1
      ArtistNode = root.AppendChild(xml.CreateElement("Artist"))
      ArtistNode.SetAttributeNode
      ArtistNode.SetAttribute("ArtistFirstName", rst.Field("ArtistFirstName").StringValue)
      ArtistNode.SetAttribute("ArtistLastName", rst.Field("ArtistLastName").StringValue)
      ArtistNode.SetAttribute("ArtistDates", rst.Field("ArtistDates").StringValue)
      rst.MoveNext
    Wend
    rst.Close
  END IF

after saving the xml, i got the following.

<?xml version="1.0" encoding="UTF-8"?>< Artists ><Artist ArtistFirstName="Salomon Guillaume" ArtistLastName="Counis" ArtistDates="1785-1859"></Artist><Artist ArtistFirstName="Francisco" ArtistLastName="De Goya" ArtistDates="1746-1828"></Artist>< /Artists >

after going through XML formatting is is as follow

<?xml version="1.0" encoding="UTF-8"?>
<Artists>
   <Artist ArtistFirstName="Salomon Guillaume" ArtistLastName="Counis" ArtistDates="1785-1859" ></Artist>
   <Artist ArtistFirstName="Francisco" ArtistLastName="De Goya" ArtistDates="1746-1828" ></Artist>
</Artists>

the question is how do i generate xml code as the one below instead of the the one above??

[code]

<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="tblArtist.xsl"?>

< Artists >

Salomon Guillaume
Counis
1785-1859


Francisco
De Goya
1746-1828


[/code][/quote]

Richard,

You are outputting your results to attributes opposed to elements which will work with XLS.

XML

[code]<?xml version="1.0" encoding="UTF-8"?>

<?xml-stylesheet type="text/xsl" href="sample.xsl"?> [/code]

XSL

[code]<?xml version="1.0"?>
<xsl:stylesheet version=“1.0” xmlns:xsl=“http://www.w3.org/1999/XSL/Transform”>
<xsl:template match="/">

<head>
  	 <link rel="stylesheet" type="text/css" href="sample.css" />
</head>
<h2>My CD Collection</h2>
<table border="1">
  <tr class="s1">
    <th>Title</th>
    <th>Artist</th>
    <th>Company</th>
    <th>Year</th>
    <th>Price</th>
  </tr>
  <xsl:for-each select="catalog/cd">
    <tr class="s2">
      <td><xsl:value-of select="@title"></xsl:value></td>
      <td><xsl:value-of select="@artist"></xsl:value></td>
      <td><xsl:value-of select="@company"></xsl:value></td>
      <td><xsl:value-of select="@year"></xsl:value></td>
      <td><xsl:value-of select="@price"></xsl:value></td>
    </tr>
  </xsl:for-each>
</table>

</xsl:stylesheet>[/code]

CSS

.s1 { Text-align:left;background-color:blue;color:white;font-size: 120%; font-style: italic; } .s2 { Text-align:left;background-color:cyan;color:black;font-size: 100%; font-style: italic; }

so what will be the dojo code look like i want to make it the elements instead of the attributes way??

oops i mean XOJO code… autocorrect change it to dojo.

i got it working with xml that has been generate by the program.

instead of using

<tr class="s2"> <td><xsl:value-of select="@title"></xsl:value></td> <td><xsl:value-of select="@artist"></xsl:value></td> <td><xsl:value-of select="@company"></xsl:value></td> <td><xsl:value-of select="@year"></xsl:value></td> <td><xsl:value-of select="@price"></xsl:value></td> </tr>

i change it to the following

<tr class="s2"> <td><xsl:value-of select="@title"></td> <td><xsl:value-of select="@artist"></td> <td><xsl:value-of select="@company"></td> <td><xsl:value-of select="@year"></td> <td><xsl:value-of select="@price"></td> </tr>

Hi Rich,

is there a reason why i can’t create xml file if i have a field with lots of information e.g. the biography field?? the following code works but if i commented out the CASE “ArtistBiography”, when it come to run and cursory on xml.SaveXML(f4), it just crash.

Dim xml As New XmlDocument
  Dim root As XmlNode
  root = xml.AppendChild(xml.CreateElement("Artists"))
  Dim ArtistNode As XmlNode
  DIM rst AS RecordSet, mySQL as String, fldcnt as integer, fldname as string
  mySQL="SELECT * FROM tblArtist ORDER BY UPPER(ArtistLastName),UPPER(ArtistFirstName)"
  rst = DoDBOpenRS(mySQL)
  if rst<>nil then
    While Not rst.eof
      ArtistNode = root.AppendChild(xml.CreateElement("Artist"))
      for fldcnt=1 to rst.FieldCount
        fldname=rst.IdxField(fldcnt).Name
        SELECT CASE fldname
        CASE "ArtistBiography"
        CASE ELSE
          ArtistNode.SetAttribute(fldname, rst.Field(fldname).StringValue)
        END SELECT
      next fldcnt
      rst.MoveNext
    Wend
    rst.Close
  END IF
  
  DIM f4 as folderitem
  f4 = GetFolderItem("").child(vFileName+".xml")
  xml.SaveXML(f4)

Hey Richard,

To answer your first question about using elements opposed to attributes, here is an example I took from one of my projects:

[code]

dim xml as XmlDocument, root, parent, child1,child2, child3, child4, child5 as XmlNode
dim f as folderitem, rs as recordset
dim db as new dbClass

f = SpecialFolder.Desktop.Child(“test.xml”)

xml = New XmlDocument
root = xml.AppendChild(xml.CreateElement("root")) // Root

rs = db.sqlQuery("select * from T_PROJECTS where project_id = " +  str(projectID))

if rs.RecordCount <> 0 then
  rs.MoveFirst
  parent = root.AppendChild(Xml.CreateElement("projectHeader"))
  child1 = parent.AppendChild(Xml.CreateElement("projectHeaderCompany"))
  child2 = parent.AppendChild(Xml.CreateElement("projectHeaderType"))
  child3 = parent.AppendChild(Xml.CreateElement("projectHeaderName"))
  child4 = parent.AppendChild(Xml.CreateElement("projectHeaderHospital"))
  child5 = parent.AppendChild(Xml.CreateElement("projectHeaderMonthYear"))
  
  child1.AppendChild(Xml.CreateTextNode("Service Team"))
  child2.AppendChild(Xml.CreateTextNode(rs.IdxField(1)))
  child3.AppendChild(Xml.CreateTextNode(rs.IdxField(2)))
  child4.AppendChild(Xml.CreateTextNode(rs.IdxField(3)))
  child5.AppendChild(Xml.CreateTextNode(rs.IdxField(4)))
  
end if

xml.SaveXml(f)[/code]

for your second question, I am not aware of any text limits an attribute can have; however, lets try to store the data to an element. if your still having issues, is there a way you can dump sample data to a sqlite database in which I can look at?

that happens to me a lot on all my devices… especially annoying as I type in Xojo at least a dozen times a day on each device (some devices like the laptop is 100s) and never type dojo. except when autocorrect corrects xojo to dojo. grrrrrrrr

ok… i change the code to use elements instead of attribute. working great now.

i also found out the exact text limits is 380 characters and it also ignore carriage return.

“Francisco Jose de Goya y Lucientes was born on March 30, 1746, in Fuendetodos, a village in northern Spain. The family later moved to Saragossa, where Goya’s father worked as a gilder. At about 14 young Goya was apprenticed to Jose Luzan, a local painter. Later he went to Italy to continue his study of art. On returning to Saragossa in 1771, he painted frescoes for the local”

when the data in the table is as follow

"Francisco Jose de Goya y Lucientes was born on March 30, 1746, in Fuendetodos, a village in northern Spain. The family later moved to Saragossa, where Goya’s father worked as a gilder. At about 14 young Goya was apprenticed to Jose Luzan, a local painter.

Later he went to Italy to continue his study of art. On returning to Saragossa in 1771, he painted frescoes for the local cathedral. These works, done in the decorative rococo tradition, established Goya’s artistic reputation. In 1773 he married Josefa Bayeu, sister of Saragossa artist Francisco Bayeu. The couple had many children, but only one–a son, Xavier–survived to adulthood. From 1775 to 1792 Goya painted cartoons (designs) for the royal tapestry factory in Madrid. "

Sounds like we are making progress :slight_smile:

Your last hurdle has to do with xsl:preserve-space in which the XSL is stripping the white spaces (such as line feed or carriage return).

This may require a bit of tinkering with the XSL file to allow white spaces.

hi Rich,

from the url you provide, “Note: Preserving white space is the default setting, so using the xsl:preserve-space element is only necessary if the xsl:strip-space element is used.” .

But the problem is i didn’t add in any line related to that… so why is it removing space?? it happen on both the xml i generate and the html created??