views:

1053

answers:

4

The Delphi 2009 XML Data Binding Wizard fails to process a simple XSD which contains a complexContent declaration (Invalid Pointer Operation).

Is it a bug or a know limitation?

Example:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema targetNamespace="http://example.org/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified">

  <xsd:complexType name="TestType">
    <xsd:complexContent>
      <xsd:restriction base="xsd:anyType">
     <xsd:attribute name="Name" type="xsd:string"/>
      </xsd:restriction>
    </xsd:complexContent>
  </xsd:complexType>

</xsd:schema>

Edit: other examples work fine, so it looks like a part of the complexContent definition causes the error. Working example:

<xsd:complexType name="pc-Typ">
  <xsd:sequence>
    <xsd:element name="name"       type="xsd:string"/>
  </xsd:sequence>
  <xsd:attribute name="id" type="xsd:integer"/>
</xsd:complexType>

<xsd:complexType name="myPC-Typ">
  <xsd:complexContent>
    <xsd:extension base="pc-Typ">
      <xsd:sequence>
        <xsd:element name="ram" type="xsd:integer"/>
      </xsd:sequence>
    </xsd:extension>
  </xsd:complexContent>
</xsd:complexType>
A: 

Confirmed your first example parses fine in xmllint.

I was surprised to see xsd:NCName, as I tend to think of it as for internal use only - but of course you can use it. I'm thinking the Dephi implementors may have made the same assumption. Try changing it to xsd:string, to help narrow it down.

And - of course - why not post this to the offical Dephi forum? (I'm sure it exists) They might fix it, or have a workaround.


BTW: it makes it easier to test XSD's if you make it a complete Schema - might be faster to get answers then, as others don't need to add in the tag.

13ren
Changed the schema as suggested with the same result. I will post it in QualityCentral too.
mjustin
A: 

I've been playing with D2007 and it seems to have problems with xsd:anyType too. Don't know any solution to this problem, though. I do know that Delphi always had minor issues with it's XML parsing functionality. Up to D7, it wasn't even truly compliant to the XML standard. So consider it just another flaw in Delphi. When using XML in my Delphi applications, I'm just ignoring this XML wizard and just import the MSXML type library instead, writing my own code to wrap around XML files. It takes a bit more time but it solved a lot of problems for my code. For one project, I even did things a bit different, creating a .NET module as wrapper around an XML file, importing this wrapper as a COM object in my Delphi project to invoke all it's functionality. It was more effective and quite fast too.

I love Delphi and it has been my first choice as development languages ever since the day it replaced Turbo/Borland Pascal, but nowadays the competition (.NET for example) has become just as powerful to use.

Workshop Alex
+1  A: 

You are best off not even using the XML Data Binding wizard. I started out using it, but found it pretty unsuitable for many XML that I work with. Then I started using IXMLDocument and IXMLNode directly, and they were a bit better, but still not particular good for performance and design reasons. Then I switched to libxml2 and have been using it ever since.

Remy Lebeau - TeamB
+1  A: 

Can I use xsd:complexContent with the Delphi XML Binding Wizard?

Yes, xsd:complexContent can be used.

I know Delphi has its flaws, but I don't blame Delphi for this schema. XSD is a rich schema language, and so is Delphi's OO class. Parts of two worlds overlap, but there are parts that won't. XML databinding is an act of translating an XML schema into OO class structure, so the schema has to be concrete enough to be expressed as class.

In this example, you are saying that TestType matches any type so long as it has a string attribute called Name. An XML validator may be ok with that kind of definition, but it's hard to define that in a single-inheritance model, since foo:Animal, foo:Plant, and foo:Mineral may all have Name attribute.

I defined an empty complexType called TestBaseType and that generated class perfectly fine.

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema targetNamespace="http://example.org/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 elementFormDefault="qualified">

  <xsd:complexType name="TestBaseType">
 <xsd:sequence>
 </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="TestType">
 <xsd:complexContent>
   <xsd:restriction base="TestBaseType">
  <xsd:attribute name="Name" type="xsd:string"/>
   </xsd:restriction>
 </xsd:complexContent>
  </xsd:complexType>
</xsd:schema>

This generated the following code:

unit test;

interface

uses xmldom, XMLDoc, XMLIntf;

type

{ Forward Decls }

  IXMLTestBaseType = interface;
  IXMLTestType = interface;

{ IXMLTestBaseType }

  IXMLTestBaseType = interface(IXMLNode)
 ['{0FBC1D84-DA5E-4315-83A9-B5FFE9528969}']
  end;

{ IXMLTestType }

  IXMLTestType = interface(IXMLTestBaseType)
 ['{12E35067-516F-4457-8C62-4131CA60D706}']
 { Property Accessors }
 function Get_Name: WideString;
 procedure Set_Name(Value: WideString);
 { Methods & Properties }
 property Name: WideString read Get_Name write Set_Name;
  end;

{ Forward Decls }

  TXMLTestBaseType = class;
  TXMLTestType = class;

{ TXMLTestBaseType }

  TXMLTestBaseType = class(TXMLNode, IXMLTestBaseType)
  protected
 { IXMLTestBaseType }
  end;

{ TXMLTestType }

  TXMLTestType = class(TXMLTestBaseType, IXMLTestType)
  protected
 { IXMLTestType }
 function Get_Name: WideString;
 procedure Set_Name(Value: WideString);
  end;

implementation

{ TXMLTestBaseType }

{ TXMLTestType }

function TXMLTestType.Get_Name: WideString;
begin
  Result := AttributeNodes['Name'].Text;
end;

procedure TXMLTestType.Set_Name(Value: WideString);
begin
  SetAttribute('Name', Value);
end;

end.
eed3si9n