Home > Delphi > Delphi xml data binding pains

Delphi xml data binding pains

September 17, 2013 Leave a comment Go to comments
xml structures

xml structures

Delphi ships with an XML data binding wizard that is, perhaps, not the most widely used utility in the Delphi toolbox but truly one of the most valuable. It really is a shame that it’s not more widely used because it can really simplify working with xml in all it’s forms. For instance, if you have a custom fileformat for your project or preferences files, then sculpting that as a schema in something like XML Spy – and then getting Delphi to generated easy to use classes to access the file is very simple.

But there are problems. Serious problems if you want to use the XML data binding wizard for anything complex and professional.

The current problem is that the import wizard screws-up namespaces. As you probably know an XSD file allows you to not only sculpt the structure of an XML file – it also allows you to pre-define data structures. Think of it as a schema that can contain delphi record definitions. An XSD file can also refer to other XSD files which is not unlike the dependencies pascal has for units, where we declare the list of units we need in the uses clause.

And this is where the XML data binding wizard simply ruins the whole game. In my example we have a huge set of XSD files that are all inter-linked and defines a large set of data structures. These structures are defined by the government – so we really dont have a choice in the matter. The data binding wizard imports everything correctly and it also generates code that matches the data structures. But it forgets to prefix various datatypes with the correct namespace token.

Example: Let’s say you have an XSD file that defines personal information. Stuff like name, address, an array of phone numbers, array of email or PM services etc.
This file imports a second file where all the datatypes are defined. So the address record etc. are defined in this second file, but put into a more meaningful structure in the first file. This is just like declaring your records and types in one unit and using them from a second unit in pascal.

The problem? XML requires you to prefix external datatypes so the parser can tell the difference. One example is a structure called “id” which defines an array of “id” items. This is perfectly valid as long as you prefix the array items correctly:

<?xml version="1.0" encoding="utf-8"?>
<MyRecord xmlns="root namespace" xmlns:tnsa="second namespace">
<id>
  <tnsa:id>
    < .. >
  </tnsa:id>
  <tnsa:id>
    < .. >
  </tnsa:id>
</id>
</MyRecord>

In the above pseudo xml output, we see that the first “id” tag has no prefix, it defaults to the root namespace. Whenever datatypes declared in “second namespace” is used, it should be prefixed with “tnsa” as defined. But the Delphi data binding wizard simply ignores this and doesn’t prefix any of the generated tags. Instead we get this:

<?xml version="1.0" encoding="utf-8"?>
<MyRecord xmlns="root namespace" xmlns:tnsa="second namespace">
<id>
  <id>
    < .. >
  </id>
  <id>
    < .. >
  </id>
</id>
</MyRecord>

Which causes a natural error because any parser that receives the generated XML will think the sub-items are of the same type as that defined in the root schema, causing a rather nasty validation exception.

It really sucks when you have to “roll your own” data binding for a product costing 10 times more than it’s competitors. This bug has been here since Delphi 7 – it really is about time the codegen was updated to correctly prefix the generated data. I was able to use the free version of visual studio to generate a C# databinding out of the box correctly, something that made me very sad for the product we all love.

    • Jon Lennart Aasenden
      April 8, 2015 at 10:18 am

      This is a well know old bug in Delphi.
      The XML binding wizard is useless with modern sheets.

  1. April 8, 2015 at 1:22 pm

    Can you tell me any alternatives to it? I dont want to change the programing language

    • Jon Lennart Aasenden
      April 8, 2015 at 7:38 pm

      Well, i ended up coding the classes by hand. I salvaged what i could from one import, then simply sad down and mapped the rest by hand – using the XML etc. framework that Delphi used.
      But sadly no, I have not yet found an alternative. Perhaps remobjects is the company to ask about this, since they have their own service importer which deals with xml and datatypes

  2. July 27, 2016 at 10:36 am

    I want to sugest an simple work-arround.
    First open the XML as a text file, and remove the namespaces/prefixes (just replace it with empty string “”), then overwrite the xml file. So you have at the end an more simple structure, without namespaces.
    Maybe is need it to remove the “namespace” also from the “declare-section”. So another replace with empty string (“”).

    I remember I had such an XML file in the past, and to process it I did this.
    So the processing was done in 2 steps:
    1. open the XML as text file, remove the prefixes (namespaces) and save the file.
    2. open it as XML and import the data.
    I build an batc-program which was doing the 2 steps and it worked perfectly for years.

    It is not the most professional method, but is very simple and it works.

  3. January 2, 2018 at 9:48 am

    I’ve reported it as a bug. Vote for it here https://quality.embarcadero.com/browse/RSP-18172?filter=-2

  1. No trackbacks yet.

Leave a comment