我可以在Delphi XML绑定向导中使用xsd:complexContent吗?

我可以在Delphi XML绑定向导中使用xsd:complexContent吗?,delphi,binding,xsd,Delphi,Binding,Xsd,Delphi 2009 XML数据绑定向导无法处理包含complexContent声明的简单XSD(无效指针操作) 这是一个bug还是一个已知的限制 例如: <?xml version="1.0" encoding="utf-8"?> <xsd:schema targetNamespace="http://example.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="

Delphi 2009 XML数据绑定向导无法处理包含complexContent声明的简单XSD(无效指针操作)

这是一个bug还是一个已知的限制

例如:

<?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>

编辑:其他示例工作正常,因此它看起来像是complexContent定义的一部分导致了错误。工作示例:

<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>

确认您的第一个示例在xmllint中解析良好

看到
xsd:NCName
,我感到很惊讶,因为我倾向于认为它仅用于内部使用——当然,您可以使用它。我认为Dephi的实现者可能也做出了同样的假设。尝试将其更改为
xsd:string
,以帮助缩小范围

当然,为什么不把这个贴到官方的德菲论坛上呢?(我相信它是存在的)他们可能会修复它,或者有一个解决办法



顺便说一句:如果你把XSD做为一个完整的模式,那么测试它就更容易了——因为其他人不需要添加标签,所以得到答案可能会更快。

我一直在玩D2007,它似乎也有XSD:anyType的问题。不过,我不知道这个问题的任何解决办法。我知道Delphi的XML解析功能总是有一些小问题。直到D7,它甚至都没有真正符合XML标准。因此,这只是Delphi中的另一个缺陷。 在Delphi应用程序中使用XML时,我只是忽略了这个XML向导,而只是导入MSXML类型库,编写自己的代码来包装XML文件。这需要更多的时间,但它为我的代码解决了很多问题。 对于一个项目,我甚至做了一些不同的事情,创建了一个.NET模块作为XML文件的包装器,将这个包装器作为COM对象导入到我的Delphi项目中,以调用它的所有功能。它更有效,速度也相当快


我喜欢Delphi,自从它取代Turbo/Borland Pascal以来,它一直是我作为开发语言的首选,但现在竞争(例如.NET)也变得同样强大了。

您最好不要使用XML数据绑定向导。我开始使用它,但发现它不适合我使用的许多XML。然后我开始直接使用IXMLDocument和IXMLNode,它们稍微好一点,但出于性能和设计原因,仍然不是特别好。然后我换了,从那以后一直在用它

我可以在Delphi XML绑定向导中使用xsd:complexContent吗

是的,
xsd:complexContent
可以使用

我知道Delphi有它的缺陷,但我不会因为这个模式而责怪Delphi。XSD是一种丰富的模式语言,Delphi的OO类也是如此。两个世界的某些部分是重叠的,但有些部分是不重叠的。XML数据绑定是将XML模式转换为OO类结构的行为,因此模式必须足够具体,才能表示为类

在本例中,您是说
TestType
匹配任何类型,只要它有一个名为
Name
string
属性。XML验证器可以使用这种定义,但很难在单个继承模型中定义,因为
foo:Animal
foo:Plant
foo:Mineral
都可能具有
Name
属性

我定义了一个名为
TestBaseType
的空complexType,生成的类非常好

<?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>

按照建议更改了架构,结果相同。我也会在QualityCentral上发布。
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.