Fixed relative schemas references in relative schema references (yo dawg...)

Fixed ItemNS for collection items where the parent node is in another namespace
This commit is contained in:
Mark van Renswoude 2017-02-17 15:27:30 +01:00
parent fe7f2eb952
commit 79d87acb61
3 changed files with 69 additions and 37 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
Units/__history/
*.local
*.identcache
bin/
lib/

View File

@ -876,6 +876,13 @@ begin
if hasPrototype and (ASection = dxsImplementation) then if hasPrototype and (ASection = dxsImplementation) then
begin begin
AWriter.WriteLine(' inherited;'); AWriter.WriteLine(' inherited;');
if AItem.IsCollection and (AItem.TargetNamespace <> AItem.CollectionItem.TargetNamespace) then
begin
AWriter.WriteLine;
AWriter.WriteLine(' ItemNS := ''%s'';', [AItem.CollectionItem.TargetNamespace]);
end;
AWriter.WriteLine('end;'); AWriter.WriteLine('end;');
AWriter.WriteLine; AWriter.WriteLine;
end; end;

View File

@ -51,7 +51,7 @@ type
function GetSchemaCount: Integer; function GetSchemaCount: Integer;
function GetSchemas(Index: Integer): TXMLDataBindingSchema; function GetSchemas(Index: Integer): TXMLDataBindingSchema;
protected protected
function LoadSchema(const AStream: TStream; const ASchemaName: String): TXMLDataBindingSchema; function LoadSchema(const AStream: TStream; const ASchemaName, ASourceFileName: String): TXMLDataBindingSchema;
function GetSchemaData(const ALocation: String; out ASourceFileName: String): TStream; function GetSchemaData(const ALocation: String; out ASourceFileName: String): TStream;
function FindSchema(const ALocation: String): TXMLDataBindingSchema; function FindSchema(const ALocation: String): TXMLDataBindingSchema;
@ -407,14 +407,11 @@ end;
procedure TXMLDataBindingGenerator.Execute(const AStream: TStream; const ASchemaName: String); procedure TXMLDataBindingGenerator.Execute(const AStream: TStream; const ASchemaName: String);
var var
schemaIndex: Integer; schemaIndex: Integer;
schema: TXMLDataBindingSchema;
begin begin
FSchemas.Clear; FSchemas.Clear;
schema := LoadSchema(AStream, ASchemaName); LoadSchema(AStream, ASchemaName, SourceFileName);
if Assigned(schema) then
schema.SourceFileName := SourceFileName;
if SchemaCount > 0 then if SchemaCount > 0 then
begin begin
@ -474,7 +471,7 @@ end;
function TXMLDataBindingGenerator.LoadSchema(const AStream: TStream; const ASchemaName: String): TXMLDataBindingSchema; function TXMLDataBindingGenerator.LoadSchema(const AStream: TStream; const ASchemaName, ASourceFileName: String): TXMLDataBindingSchema;
procedure HandleDocRefs(const ADocRefs: IXMLSchemaDocRefs; ASchema: TXMLDataBindingSchema); procedure HandleDocRefs(const ADocRefs: IXMLSchemaDocRefs; ASchema: TXMLDataBindingSchema);
var var
@ -488,48 +485,59 @@ function TXMLDataBindingGenerator.LoadSchema(const AStream: TStream; const ASche
begin begin
for refIndex := 0 to Pred(ADocRefs.Count) do for refIndex := 0 to Pred(ADocRefs.Count) do
begin begin
location := ADocRefs[refIndex].SchemaLocation; location := ADocRefs[refIndex].SchemaLocation;
schemaName := ChangeFileExt(ExtractFileName(location), ''); schemaName := ChangeFileExt(ExtractFileName(location), '');
refSchema := FindSchema(schemaName); refSchema := FindSchema(schemaName);
if not Assigned(refSchema) then if not Assigned(refSchema) then
begin begin
refStream := GetSchemaData(location, sourceFileName); refStream := GetSchemaData(location, sourceFileName);
if Assigned(refStream) then if Assigned(refStream) then
try try
refSchema := LoadSchema(refStream, schemaName); refSchema := LoadSchema(refStream, schemaName, sourceFileName);
if Assigned(refSchema) then
refSchema.SourceFileName := sourceFileName;
finally finally
FreeAndNil(refStream); FreeAndNil(refStream);
end; end;
end; end;
if Assigned(refSchema) then if Assigned(refSchema) then
begin
// Update the schema location to an absolute path,
// the Delphi XMLSchema unit has trouble resolving relative references
// in a relatively referenced file.
ADocRefs[refIndex].SchemaLocation := refSchema.SourceFileName;
ASchema.AddInclude(refSchema); ASchema.AddInclude(refSchema);
end;
end; end;
end; end;
var var
schemaDoc: IXMLSchemaDoc; currentDir: string;
schemaDef: IXMLSchemaDef; schemaDoc: IXMLSchemaDoc;
schemaDef: IXMLSchemaDef;
begin begin
schemaDoc := TXMLSchemaDoc.Create(nil); schemaDoc := TXMLSchemaDoc.Create(nil);
schemaDoc.LoadFromStream(AStream); schemaDoc.LoadFromStream(AStream);
schemaDef := schemaDoc.SchemaDef; schemaDef := schemaDoc.SchemaDef;
Result := TXMLDataBindingSchema.Create(Self); Result := TXMLDataBindingSchema.Create(Self);
Result.SchemaDef := schemaDef; Result.SchemaDef := schemaDef;
Result.SchemaName := ASchemaName; Result.SchemaName := ASchemaName;
Result.SourceFileName := ExpandFileName(ASourceFileName);
FSchemas.Add(Result); FSchemas.Add(Result);
{ Handle imports / includes } currentDir := GetCurrentDir;
HandleDocRefs(schemaDef.SchemaImports, Result); SetCurrentDir(ExtractFilePath(Result.SourceFileName));
HandleDocRefs(schemaDef.SchemaIncludes, Result); try
{ Handle imports / includes }
HandleDocRefs(schemaDef.SchemaImports, Result);
HandleDocRefs(schemaDef.SchemaIncludes, Result);
finally
SetCurrentDir(currentDir);
end;
end; end;
@ -549,7 +557,7 @@ begin
if FileExists(includePath + ALocation) then if FileExists(includePath + ALocation) then
begin begin
ASourceFileName := includePath + ALocation; ASourceFileName := ExpandFileName(includePath + ALocation);
Result := TFileStream.Create(ASourceFileName, fmOpenRead or fmShareDenyNone); Result := TFileStream.Create(ASourceFileName, fmOpenRead or fmShareDenyNone);
break; break;
end; end;
@ -581,17 +589,23 @@ begin
if ASchema.ItemsGenerated then if ASchema.ItemsGenerated then
exit; exit;
OutputDebugString(PChar('> ' + ASchema.SchemaName));
ASchema.ItemsGenerated := True; ASchema.ItemsGenerated := True;
OutputDebugString('Includes...');
{ First generate the objects for all includes and imports, so we can get { First generate the objects for all includes and imports, so we can get
proper references. } proper references. }
for includeIndex := 0 to Pred(ASchema.IncludeCount) do for includeIndex := 0 to Pred(ASchema.IncludeCount) do
GenerateSchemaObjects(ASchema.Includes[includeIndex], False); GenerateSchemaObjects(ASchema.Includes[includeIndex], False);
OutputDebugString(PChar(ASchema.SchemaName + ': Generate objects'));
GenerateElementObjects(ASchema, ARootDocument); GenerateElementObjects(ASchema, ARootDocument);
GenerateComplexTypeObjects(ASchema); GenerateComplexTypeObjects(ASchema);
GenerateSimpleTypeObjects(ASchema); GenerateSimpleTypeObjects(ASchema);
GenerateAttributeObjects(ASchema); GenerateAttributeObjects(ASchema);
OutputDebugString(PChar('< ' + ASchema.SchemaName));
end; end;
@ -676,22 +690,27 @@ begin
end else if simpleType.DerivationMethod = sdmRestriction then end else if simpleType.DerivationMethod = sdmRestriction then
begin begin
baseType := simpleType.BaseType; baseType := simpleType.BaseType;
if Assigned(baseType) then
while Assigned(baseType.BaseType) do
baseType := baseType.BaseType;
if not baseType.IsComplex then
begin begin
if not VarIsNull(simpleType.SchemaDef.TargetNamespace) then while Assigned(baseType.BaseType) do
begin baseType := baseType.BaseType;
namespace := simpleType.SchemaDef.TargetNamespace;
if namespace = Schemas[0].TargetNamespace then
namespace := '';
end;
simpleTypeAlias := TXMLDataBindingSimpleTypeAliasItem.Create(Self, baseType, simpleType.Name); if not baseType.IsComplex then
simpleTypeAlias.TargetNamespace := namespace; begin
ASchema.AddItem(simpleTypeAlias); if not VarIsNull(simpleType.SchemaDef.TargetNamespace) then
begin
namespace := simpleType.SchemaDef.TargetNamespace;
if namespace = Schemas[0].TargetNamespace then
namespace := '';
end;
simpleTypeAlias := TXMLDataBindingSimpleTypeAliasItem.Create(Self, baseType, simpleType.Name);
simpleTypeAlias.TargetNamespace := namespace;
ASchema.AddItem(simpleTypeAlias);
end;
end else
begin
// ...I literally can't even.
end; end;
end; end;
end; end;
@ -1126,6 +1145,7 @@ begin
// #ToDo1 -oMvR: set type "union" // #ToDo1 -oMvR: set type "union"
ASchema.AddItem(simpleAliasItem); ASchema.AddItem(simpleAliasItem);
break;
end end
else else
typeDef := nil; typeDef := nil;