The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 2,117 other followers

Fixing the WSDLImp command-line Delphi WSDL importer to parse WSDL files including XSD files using xsd:group at the top level

Posted by jpluimers on 2018/05/24

I finally found out the cause of the Delphi WSDL Importer generating wrong .pas files when the WSDL file includes an XSD file that uses an xsd:group (see below) at the top-level.

The resulting access violation was caused by forgetting a nil check for a Context (at the top-level it is nil because there is no encompassing type yet; xsd:group can be at the top-level).

There might also be other WSDL/XSD constructs leading to the same code path: a good set of WSDL/XSD combination would be needed for proper integration testing on this. Hopefully, Embarcadero has such a set.

Patches

All patches are at https://gist.github.com/jpluimers/2824c03ae816229a53ffa4830b2d6208. If you need a binary build that includes the patches, drop a comment below.

Before fixing, I had to get it building which required modifying the search path and output path (both see Delphi WSDL importer compiler defines). This is the first patch below (which results includes a huge .dproj change as that’s what the IDE does to a project when you change just a few simple things).

The second patch below is the fix.

The fix is to replace if (TypeDef.IsAnonymous) then by if (TypeDef.IsAnonymous) and Assigned(Context) then in side the function TWSDLTypeImporter.AddComplexType of WSDLImpWriter.pas.

After careful checking of the group handling (around etElementGroup, cmGroupRef,  xtiElemGroupIXMLElementGroup, IXMLElementGroups), no other fixes are needed as the rest of the xsd:group handling functions correctly at least for the WSDL/XSD combinations I had to import.

During fixing, I found some compiler defines would produce much more output. That output tremendously helped finding out if xsd:group handling was indeed correct.

In the third patch, I have added another modification that introduces a new -logall command-line parameter that enables all these in one go.

I have handed over the patches through internal channels in order to circumvent a long and tedious QC/QualityPortal process. Hopefully they will make it in the next major Delphi version.

Related

Patches generated by following the steps in [WayBack] Generate a git patch for a specific commit – Stack Overflow:

git format-patch -1 <<commit-SHA>>

Command-line parameters

The WSDLImp has many command-line parameters, some of which are not accessible from the IDE expert. More information on these at:

xsd:group

An xsd:group contains a group of definitions. It is similar to a list of fields in a record/class/interface in Delphi that you can use in multiple record/class/interface definitions. The group only has a name at the XSD level, but not at the Delphi generated code level: there the group is expanded in each place it is used.

More information: [WayBack] xsd – How to use the xml schema group element – Stack Overflow

–jeroen

Patches

From 4e5ff27613499f82380a839968ad2b451c624672 Mon Sep 17 00:00:00 2001
From: Jeroen Pluimers <jeroen.gist.github.com@pluimers.com>
Date: Tue, 15 May 2018 15:13:00 +0200
Subject: [PATCH] fix search and output path:
search path $(BDS)\source\soap will find CompVer.inc
old output path $(BDS)\bin only works under UAC and overwrites the
stock output; new path .\$(Platform)\$(Config) puts it along the .DCU
files
WSDLImp.dproj | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++–
1 file changed, 140 insertions(+), 4 deletions(-)
diff –git a/WSDLImp.dproj b/WSDLImp.dproj
index 842d381..646e287 100644
— a/WSDLImp.dproj
+++ b/WSDLImp.dproj
@@ -7,12 +7,32 @@
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>16.0</ProjectVersion>
+ <ProjectVersion>18.3</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''">
+ <Base_Android>true</Base_Android>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='iOSDevice32' and '$(Base)'=='true') or '$(Base_iOSDevice32)'!=''">
+ <Base_iOSDevice32>true</Base_iOSDevice32>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Base)'=='true') or '$(Base_iOSDevice64)'!=''">
+ <Base_iOSDevice64>true</Base_iOSDevice64>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='iOSSimulator' and '$(Base)'=='true') or '$(Base_iOSSimulator)'!=''">
+ <Base_iOSSimulator>true</Base_iOSSimulator>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
@@ -23,11 +43,29 @@
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='iOSDevice32' and '$(Cfg_2)'=='true') or '$(Cfg_2_iOSDevice32)'!=''">
+ <Cfg_2_iOSDevice32>true</Cfg_2_iOSDevice32>
+ <CfgParent>Cfg_2</CfgParent>
+ <Cfg_2>true</Cfg_2>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Cfg_2)'=='true') or '$(Cfg_2_iOSDevice64)'!=''">
+ <Cfg_2_iOSDevice64>true</Cfg_2_iOSDevice64>
+ <CfgParent>Cfg_2</CfgParent>
+ <Cfg_2>true</Cfg_2>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='iOSSimulator' and '$(Cfg_2)'=='true') or '$(Cfg_2_iOSSimulator)'!=''">
+ <Cfg_2_iOSSimulator>true</Cfg_2_iOSSimulator>
+ <CfgParent>Cfg_2</CfgParent>
+ <Cfg_2>true</Cfg_2>
+ <Base>true</Base>
+ </PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<SanitizedProjectName>WSDLImp</SanitizedProjectName>
<DCC_OutputDRCFile>true</DCC_OutputDRCFile>
<DCC_UnitSearchPath>.\$(Platform)\$(Config);$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<DCC_ExeOutput>$(BDS)\bin</DCC_ExeOutput>
+ <DCC_UnitSearchPath>.\$(Platform)\$(Config);$(BDS)\source\soap;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
+ <DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<Manifest_File>None</Manifest_File>
@@ -40,6 +78,87 @@
<DCC_K>false</DCC_K>
<DCC_E>false</DCC_E>
<DCC_F>false</DCC_F>
+ <Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
+ <Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base_Android)'!=''">
+ <VerInfo_Keys>package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=</VerInfo_Keys>
+ <BT_BuildType>Debug</BT_BuildType>
+ <Android_LauncherIcon36>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png</Android_LauncherIcon36>
+ <Android_LauncherIcon48>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png</Android_LauncherIcon48>
+ <Android_LauncherIcon72>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png</Android_LauncherIcon72>
+ <Android_LauncherIcon96>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png</Android_LauncherIcon96>
+ <Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144>
+ <Android_SplashImage426>$(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png</Android_SplashImage426>
+ <Android_SplashImage470>$(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png</Android_SplashImage470>
+ <Android_SplashImage640>$(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png</Android_SplashImage640>
+ <Android_SplashImage960>$(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png</Android_SplashImage960>
+ <AUP_ACCESS_COARSE_LOCATION>true</AUP_ACCESS_COARSE_LOCATION>
+ <AUP_ACCESS_FINE_LOCATION>true</AUP_ACCESS_FINE_LOCATION>
+ <AUP_CALL_PHONE>true</AUP_CALL_PHONE>
+ <AUP_CAMERA>true</AUP_CAMERA>
+ <AUP_INTERNET>true</AUP_INTERNET>
+ <AUP_READ_CALENDAR>true</AUP_READ_CALENDAR>
+ <AUP_READ_EXTERNAL_STORAGE>true</AUP_READ_EXTERNAL_STORAGE>
+ <AUP_WRITE_CALENDAR>true</AUP_WRITE_CALENDAR>
+ <AUP_WRITE_EXTERNAL_STORAGE>true</AUP_WRITE_EXTERNAL_STORAGE>
+ <AUP_READ_PHONE_STATE>true</AUP_READ_PHONE_STATE>
+ <EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar</EnabledSysJars>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base_iOSDevice32)'!=''">
+ <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera</VerInfo_Keys>
+ <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
+ <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+ <BT_BuildType>Debug</BT_BuildType>
+ <VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId>
+ <iPhone_AppIcon60>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png</iPhone_AppIcon60>
+ <iPhone_AppIcon120>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png</iPhone_AppIcon120>
+ <iPhone_Spotlight40>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png</iPhone_Spotlight40>
+ <iPhone_Spotlight80>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png</iPhone_Spotlight80>
+ <iPad_SpotLight40>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png</iPad_SpotLight40>
+ <iPad_SpotLight80>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png</iPad_SpotLight80>
+ <iPad_AppIcon76>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png</iPad_AppIcon76>
+ <iPad_AppIcon152>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png</iPad_AppIcon152>
+ <iPad_Launch768x1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png</iPad_Launch768x1024>
+ <iPad_Launch1024x768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png</iPad_Launch1024x768>
+ <iPad_Launch1536x2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png</iPad_Launch1536x2048>
+ <iPad_Launch2048x1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png</iPad_Launch2048x1536>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base_iOSDevice64)'!=''">
+ <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera</VerInfo_Keys>
+ <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
+ <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+ <BT_BuildType>Debug</BT_BuildType>
+ <VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId>
+ <iPhone_AppIcon60>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png</iPhone_AppIcon60>
+ <iPhone_AppIcon120>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png</iPhone_AppIcon120>
+ <iPhone_Spotlight40>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png</iPhone_Spotlight40>
+ <iPhone_Spotlight80>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png</iPhone_Spotlight80>
+ <iPad_SpotLight40>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png</iPad_SpotLight40>
+ <iPad_SpotLight80>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png</iPad_SpotLight80>
+ <iPad_AppIcon76>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png</iPad_AppIcon76>
+ <iPad_AppIcon152>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png</iPad_AppIcon152>
+ <iPad_Launch768x1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png</iPad_Launch768x1024>
+ <iPad_Launch1024x768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png</iPad_Launch1024x768>
+ <iPad_Launch1536x2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png</iPad_Launch1536x2048>
+ <iPad_Launch2048x1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png</iPad_Launch2048x1536>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base_iOSSimulator)'!=''">
+ <VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSCameraUsageDescription=The reason for accessing the camera</VerInfo_Keys>
+ <VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
+ <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+ <iPhone_AppIcon60>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png</iPhone_AppIcon60>
+ <iPhone_AppIcon120>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png</iPhone_AppIcon120>
+ <iPhone_Spotlight40>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png</iPhone_Spotlight40>
+ <iPhone_Spotlight80>$(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png</iPhone_Spotlight80>
+ <iPad_SpotLight40>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png</iPad_SpotLight40>
+ <iPad_SpotLight80>$(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png</iPad_SpotLight80>
+ <iPad_AppIcon76>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png</iPad_AppIcon76>
+ <iPad_AppIcon152>$(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png</iPad_AppIcon152>
+ <iPad_Launch768x1024>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png</iPad_Launch768x1024>
+ <iPad_Launch1024x768>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png</iPad_Launch1024x768>
+ <iPad_Launch1536x2048>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png</iPad_Launch1536x2048>
+ <iPad_Launch2048x1536>$(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png</iPad_Launch2048x1536>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
@@ -52,6 +171,15 @@
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_2_iOSDevice32)'!=''">
+ <DCC_RemoteDebug>true</DCC_RemoteDebug>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_2_iOSDevice64)'!=''">
+ <DCC_RemoteDebug>true</DCC_RemoteDebug>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_2_iOSSimulator)'!=''">
+ <DCC_RemoteDebug>true</DCC_RemoteDebug>
+ </PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
@@ -111,9 +239,17 @@
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
</VersionInfoKeys>
<Excluded_Packages/>
+ <Excluded_Packages>
+ <Excluded_Packages Name="$(BDSBIN)\dcloffice2k250.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
+ <Excluded_Packages Name="$(BDSBIN)\dclofficexp250.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
+ </Excluded_Packages>
</Delphi.Personality>
<Platforms>
+ <Platform value="Android">False</Platform>
+ <Platform value="iOSDevice32">False</Platform>
+ <Platform value="iOSDevice64">False</Platform>
+ <Platform value="iOSSimulator">False</Platform>
+ <Platform value="Linux64">False</Platform>
<Platform value="OSX32">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
2.14.3 (Apple Git-98)

From b9e3f63d38b4cc70c4820bcc530ff700b36311c9 Mon Sep 17 00:00:00 2001
From: Jeroen Pluimers <jeroen.gist.github.com@pluimers.com>
Date: Wed, 16 May 2018 13:18:19 +0200
Subject: [PATCH] Fixes TWSDLTypeImporter.AddComplexType Access Violation
This occurs for instance when a WSDL document includes an XSD document that uses xsd:group at the global level to define a group of elements.
It could occur in other circumstances as well, and would allow the importer to continue and emit a .pas file with missing imports.
The IDE wizard version willnot display the Access Violation at all (nor any other importer console output), so there would be no clue for the source of the problem.
Also adds the $(BDS)\source\xml to the unit search path so it is a lot easier to debug the XML handling of the XSD.
WSDLImp.dproj | 2 +-
WSDLImpWriter.pas | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff –git a/WSDLImp.dproj b/WSDLImp.dproj
index 646e287..bb03e44 100644
— a/WSDLImp.dproj
+++ b/WSDLImp.dproj
@@ -64,7 +64,7 @@
<PropertyGroup Condition="'$(Base)'!=''">
<SanitizedProjectName>WSDLImp</SanitizedProjectName>
<DCC_OutputDRCFile>true</DCC_OutputDRCFile>
<DCC_UnitSearchPath>.\$(Platform)\$(Config);$(BDS)\source\soap;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
+ <DCC_UnitSearchPath>.\$(Platform)\$(Config);$(BDS)\source\soap;$(BDS)\source\xml;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
diff –git a/WSDLImpWriter.pas b/WSDLImpWriter.pas
index 3774c31..25a5113 100644
— a/WSDLImpWriter.pas
+++ b/WSDLImpWriter.pas
@@ -1960,7 +1960,7 @@ var
Part: TWSDLPart;
AName, ANamespace: DOMString;
begin
if (TypeDef.IsAnonymous) then
+ if (TypeDef.IsAnonymous) and Assigned(Context) then
begin
{$IFDEF COLLAPSE_ANONYMOUS_COMPLEXTYPES}
if (Context.DataKind = wtNotDefined) then
2.14.3 (Apple Git-98)

From 70cd78c58f919c50a8b64c6add83bc1a11bc3a92 Mon Sep 17 00:00:00 2001
From: Jeroen Pluimers <jeroen.gist.github.com@pluimers.com>
Date: Wed, 16 May 2018 13:44:29 +0200
Subject: [PATCH] Add -logall option that in one sweep enables all LOG_ defined
functions inside WSDLImpWriter.
WSDLImp.dpr | 1 +
WSDLImpConst.pas | 7 ++++
WSDLImpWriter.pas | 118 +++++++++++++++++++++++++++++++———————–
3 files changed, 75 insertions(+), 51 deletions(-)
diff –git a/WSDLImp.dpr b/WSDLImp.dpr
index 3bc4928..30731c3 100644
— a/WSDLImp.dpr
+++ b/WSDLImp.dpr
@@ -371,6 +371,7 @@ var
GetVerboseOption(S, sPassOption, Password) or
GetVerboseOption(S, sProxyOption, Proxy) or
GetVerboseOption(S, wfDebug) or
+ GetVerboseOption(S, wfLogAllImpWriter) or
GetVerboseOption(S, sDumpSettingsOption, DumpSettings) or
GetVerboseOption(S, sXMLSchemaFile, XMLSchemaFile) or
GetVerboseOption(S, sSkipURLOption, WSDLImportInfo.SkipURLs) or
diff –git a/WSDLImpConst.pas b/WSDLImpConst.pas
index 953b2ca..f0f1b70 100644
— a/WSDLImpConst.pas
+++ b/WSDLImpConst.pas
@@ -894,6 +894,7 @@ sUseXSTypeForSimpleNillable = 'Use T&XSxxxx classes for simple nillable types';
sUseScopedEnumerations = '&Generate scoped enumerations';
sCreateArrayElemTypeAlias = 'Generate alias for the element of pure collections';
+sLogAllImpWriterOptForCommandLineHelp = 'Perform much more logging from the Importer/Writer logic';
sVerboseOptForCommandLineHelp = 'Generate verbose information about types and interfaces';
sSkipHTTPBindOptForCommandLineHelp = 'Process only SOAP binding types';
sMapNamedArraysForCommandLineHelp = 'Map pure collections to wrapper class types';
@@ -974,6 +975,7 @@ CannotUnwrapStr: array[CannotUnwrap] of String = (
ProcessFaults = 'ProcessFaults'; { do not localize }
SkipUnusedTypes = 'SkipUnusedTypes'; { do not localize }
SkipHttpBindings = 'SkipHttpBindings'; { do not localize }
+ LogAllImpWriterMode = 'LogAllImpWriterMode'; { do not localize }
VerboseMode = 'VerboseMode'; { do not localize }
ValidateEnumMembers = 'ValidateEnumMembers'; { do not localize }
ProcessHeaders = 'ProcessHeaders'; { do not localize }
@@ -991,6 +993,7 @@ CannotUnwrapStr: array[CannotUnwrap] of String = (
OptStrings: array[WSDLGenFlags] of string =
('', { wfDebug }
+ LogAllImpWriterMode, { wfLogAllImpWriter }
VerboseMode, { wfVerbose }
SkipHttpBindings, { wfSkipHttpBindings }
OneParamIsReturnSetting, { wfOneOutIsReturn }
@@ -1029,6 +1032,7 @@ CannotUnwrapStr: array[CannotUnwrap] of String = (
OptDescriptions: array[WSDLGenFlags] of string =
('', { wfDebug }
+ '', { wfLogAllImpWriter }
sVerboseOpt, { wfVerbose }
sSkipHTTPBindOpt, { wfSkipHttpBindings }
sOneOutParamIsReturn, { wfOneOutIsReturn }
@@ -1067,6 +1071,7 @@ CannotUnwrapStr: array[CannotUnwrap] of String = (
OptDescriptionsForCommandLineHelp: array[WSDLGenFlags] of string =
('', { wfDebug }
+ sLogAllImpWriterOptForCommandLineHelp, { wfLogAllImpWriter }
sVerboseOptForCommandLineHelp, { wfVerbose }
sSkipHTTPBindOptForCommandLineHelp, { wfSkipHttpBindings }
sOneOutParamIsReturnForCommandLineHelp, { wfOneOutIsReturn }
@@ -1105,6 +1110,7 @@ CannotUnwrapStr: array[CannotUnwrap] of String = (
OptHiddenOptions: array[WSDLGenFlags] of Boolean =
(True, { wfDebug } // Debugging output
+ False, { wfLogAllImpWriter }
False, { wfVerbose }
True, { wfSkipHttpBindings } //Removed temporarily until it can be properly implemented
False, { wfOneOutIsReturn }
@@ -1143,6 +1149,7 @@ CannotUnwrapStr: array[CannotUnwrap] of String = (
OptCommandLineFlags: array[WSDLGenFlags] of string =
('debug', { wfDebug }
+ 'logall', { wfLogAllImpWriter }
'v', { wfVerbose }
'', { wfSkipHttpBindings }
'o', { wfOneOutIsReturn }
diff –git a/WSDLImpWriter.pas b/WSDLImpWriter.pas
index 25a5113..905e3a9 100644
— a/WSDLImpWriter.pas
+++ b/WSDLImpWriter.pas
@@ -48,6 +48,14 @@ uses
Classes, TypInfo, xmldom, XmlSchema, WSDLIntf, WSDLBind, InvokeRegistry, WSDLItems,
UDDIHlprDesign, Contnrs, WSDLModelIntf;
+const
+ LogTypesReading = {$IFDEF LOG_TYPES_READING} True {$ELSE} False {$ENDIF LOG_TYPES_READING};
+ LogTypesWriting = {$IFDEF LOG_TYPES_WRITING} True {$ELSE} False {$ENDIF LOG_TYPES_WRITING};
+ LogTypesUnwind = {$IFDEF LOG_TYPES_UNWIND} True {$ELSE} False {$ENDIF LOG_TYPES_UNWIND};
+ LogTypesSorting = {$IFDEF LOG_TYPES_SORTING} True {$ELSE} False {$ENDIF LOG_TYPES_SORTING};
+ LogTypesLookup = {$IFDEF LOG_TYPES_LOOKUP} True {$ELSE} False {$ENDIF LOG_TYPES_LOOKUP};
+ LogTypesDump = {$IFDEF LOG_TYPES_DUMP} True {$ELSE} False {$ENDIF LOG_TYPES_DUMP};
+
const
SMultiPart = 'multipartRelated';
SSoapAttachment = 'TSOAPAttachment';
@@ -187,6 +195,7 @@ type
{ Flags to configure writer }
WSDLGenFlags = (wfDebug,
+ wfLogAllImpWriter, { enable all LOG_* functionality }
wfVerbose,
wfSkipHttpBindings, { Skip http bound bindings }
wfOneOutIsReturn, { Convert single out to retval }
@@ -304,6 +313,7 @@ type
function TypeNameFromTypeInfo(TypeInfo: pTypeInfo): DOMString; virtual;
function GetTypeInfoPad: DOMString; virtual;
function GetDebugMode: boolean;
+ function GetLogAllImpWriterMode: boolean;
function GetVerboseMode: boolean;
function IsCaseSensitive: Boolean; virtual;
function RemapMembersOfTypeName: boolean; virtual;
@@ -351,6 +361,7 @@ type
property OnWrite: TWriteProc read FOnWrite write FOnWrite;
property TypeInfoPad: DOMString read GetTypeInfoPad;
property DebugMode: boolean read GetDebugMode;
+ property LogAllImpWriterMode: boolean read GetLogAllImpWriterMode;
property Verbose: boolean read GetVerboseMode;
property WritingEnums: boolean read FWritingEnums write FWritingEnums;
end;
@@ -574,9 +585,7 @@ type
function AddAttribute(const TypeDef: IXMLAttributeDef; const Context: IWSDLType): IWSDLType;
procedure UpdateWoHasOptions(Opt: WSDLImporterOpts);
{$IFDEF LOG_TYPES_READING}
procedure LogTypeReading(Item: IXMLSchemaItem);
{$ENDIF}
public
constructor Create; virtual;
@@ -1413,10 +1422,11 @@ begin
MarkTypes;
{ Sort Types }
SortTypes;
{$IFDEF LOG_TYPES_DUMP}
{ Dump Types }
DumpTypes;
{$ENDIF}
+ if LogTypesDump or (wfLogAllImpWriter in Global_WSDLGenFlags) then
+ begin
+ { Dump Types }
+ DumpTypes;
+ end;
end;
procedure TWSDLImporter.ImportsCallback(const Options: IterateImportOptions;
@@ -1706,21 +1716,18 @@ begin
WriteFeedback(sFeedbackImp+sLineBreak, [SchemaLoc]);
end;
{$IFDEF LOG_TYPES_READING}
procedure TWSDLTypeImporter.LogTypeReading(Item: IXMLSchemaItem);
begin
WriteFeedback(sReadingType+sLineBreak, [Item.Name]);
+ if LogTypesReading or (wfLogAllImpWriter in Global_WSDLGenFlags) then
+ WriteFeedback(sReadingType+sLineBreak, [Item.Name]);
end;
{$ENDIF}
function TWSDLTypeImporter.Visit(const Item: IXMLElementDef;
const ElementTypes: TElementTypes;
const CompositorId: Integer;
const Context: XMLVisitorContext): XMLVisitorContext;
begin
{$IFDEF LOG_TYPES_READING}
LogTypeReading(Item);
{$ENDIF}
// Skip Global Groups as it's a top-level that names the group
if (ElementTypes = [etGlobal, etElementGroup]) then
@@ -1734,33 +1741,25 @@ end;
function TWSDLTypeImporter.Visit(const Item: IXMLAttributeDef; const Context: XMLVisitorContext): XMLVisitorContext;
begin
{$IFDEF LOG_TYPES_READING}
LogTypeReading(Item);
{$ENDIF}
Result := AddAttribute(Item, Context);
end;
function TWSDLTypeImporter.Visit(const Item: IXMLComplexTypeDef; const Context: XMLVisitorContext): XMLVisitorContext;
begin
{$IFDEF LOG_TYPES_READING}
LogTypeReading(Item);
{$ENDIF}
Result := AddComplexType(Item, Context);
end;
function TWSDLTypeImporter.Visit(const Item: IXMLAttributeGroup; const Context: XMLVisitorContext): XMLVisitorContext;
begin
{$IFDEF LOG_TYPES_READING}
LogTypeReading(Item);
{$ENDIF}
Result := AddAttributeGroup(Item, Context);
end;
function TWSDLTypeImporter.Visit(const Item: IXMLElementGroup; const Context: XMLVisitorContext): XMLVisitorContext;
begin
{$IFDEF LOG_TYPES_READING}
LogTypeReading(Item);
{$ENDIF}
Result := AddElementGroup(Item, Context);
end;
@@ -1800,9 +1799,7 @@ end;
function TWSDLTypeImporter.Visit(const Item: IXMLSimpleTypeDef;const Context: XMLVisitorContext): XMLVisitorContext;
begin
{$IFDEF LOG_TYPES_READING}
LogTypeReading(Item);
{$ENDIF}
Result := AddSimpleType(Item, Context);
end;
@@ -3504,10 +3501,11 @@ procedure TWSDLImporter.SortTypes;
function Compare(const A: IWSDLType; const B: IWSDLType): Integer;
begin
Result := CompareHelper(A, B);
{$IFDEF LOG_TYPES_SORTING}
if (Result <> 0) and (Result = CompareHelper(B, A)) then
WriteFeedback(sUnableToSortTypes+sLineBreak, [A.Name, B.Name]);
{$ENDIF}
+ if LogTypesSorting or (wfLogAllImpWriter in Global_WSDLGenFlags) then
+ begin
+ if (Result <> 0) and (Result = CompareHelper(B, A)) then
+ WriteFeedback(sUnableToSortTypes+sLineBreak, [A.Name, B.Name]);
+ end;
end;
procedure GetDependentTypes(const WSDLType: IWSDLType; var Types: IWSDLTypeArray); overload;
@@ -5153,9 +5151,10 @@ begin
if ((TypeKinds = []) or (WSDLType.DataKind in TypeKinds)) and
((ExcludeKinds=[])or not (WSDLType.DataKind in ExcludeKinds)) then
begin
{$IFDEF LOG_TYPES_WRITING}
WriteFeedback(sWritingType+sLineBreak, [WSDLType.Name]);
{$ENDIF}
+ if LogTypesWriting or LogAllImpWriterMode then
+ begin
+ WriteFeedback(sWritingType+sLineBreak, [WSDLType.Name]);
+ end;
{ ================================================================
The following logic relies on the fact that all enumerations
@@ -5223,6 +5222,11 @@ begin
Result := wfDebug in Global_WSDLGenFlags;
end;
+function TWSDLWriter.GetLogAllImpWriterMode: boolean;
+begin
+ Result := wfLogAllImpWriter in Global_WSDLGenFlags;
+end;
+
function TWSDLWriter.GetVerboseMode: boolean;
begin
Result := wfVerbose in Global_WSDLGenFlags;
@@ -7171,16 +7175,21 @@ end;
{ TWSDLType }
function UnwindType(const WSDLType: IWSDLType; ClsOnly: Boolean): IWSDLType;
+var
+ DoLogTypesUnwind: Boolean;
begin
Result := WSDLType;
{$IFDEF LOG_TYPES_UNWIND}
WriteLn(sDottedLine);
{$ENDIF}
+ DoLogTypesUnwind := LogTypesUnwind { or (wfLogAllImpWriter in Global_WSDLGenFlags) { if you add the "or", you get a truckload of dashed lines };
+ if DoLogTypesUnwind then
+ begin
+ WriteLn(sDottedLine);
+ end;
while (Result.DataKind = wtAlias) do
begin
{$IFDEF LOG_TYPES_UNWIND}
WriteLn(Result.Name+':'+Result.Namespace);
{$ENDIF}
+ if LogTypesUnwind then
+ begin
+ WriteLn(Result.Name+':'+Result.Namespace);
+ end;
{ Only unwind class aliases }
if ClsOnly and (WSDLType.BaseType.DataKind <> wtClass) then
Exit;
@@ -7527,6 +7536,7 @@ function TWSDLTypes.FindType(const Name, Namespace: DOMString;
Create: Boolean): IWSDLType;
var
+ DoLogTypesLookup: Boolean;
WSDLType: IWSDLType;
I: Integer;
{$IFDEF CACHE_TYPES}
@@ -7534,11 +7544,13 @@ var
TypeVals: PointerArray;
{$ENDIF}
begin
{$IFDEF LOG_TYPES_LOOKUP}
Write('LOOKUP: ' + Name + ':' + Namespace + ', +['+
SetToStr(TypeInfo(XMLItemInfo), Word(HasThese), False) + '], -['+
SetToStr(TypeInfo(XMLItemInfo), Word(DoesNotHaveThese), False) + '] ');
{$ENDIF}
+ DoLogTypesLookup := LogTypesLookup or (wfLogAllImpWriter in Global_WSDLGenFlags) ;
+ if DoLogTypesLookup then
+ begin
+ Write('LOOKUP: ' + Name + ':' + Namespace + ', +['+
+ SetToStr(TypeInfo(XMLItemInfo), Word(HasThese), False) + '], -['+
+ SetToStr(TypeInfo(XMLItemInfo), Word(DoesNotHaveThese), False) + '] ');
+ end;
Assert(HasThese * DoesNotHaveThese = [],
Format('TWSDLTypes.FindType: "%s:%s " +[%s] -[%s]: Invalid XMLItemInfo',
[Name, Namespace, SetToStr(TypeInfo(XMLItemInfo), Word(HasThese), False),
@@ -7555,9 +7567,10 @@ begin
(DoesNotHaveThese * WSDLType.XMLItemInfo = []) then
begin
Result := WSDLType;
{$IFDEF LOG_TYPES_LOOKUP}
WriteLn('FOUND');
{$ENDIF}
+ if DoLogTypesLookup then
+ begin
+ WriteLn('FOUND');
+ end;
Exit;
end;
end;
@@ -7572,9 +7585,10 @@ begin
(DoesNotHaveThese * WSDLType.XMLItemInfo = []) then
begin
Result := WSDLType;
{$IFDEF LOG_TYPES_LOOKUP}
WriteLn('FOUND');
{$ENDIF}
+ if DoLogTypesLookup then
+ begin
+ WriteLn('FOUND');
+ end;
Exit;
end;
end;
@@ -7583,15 +7597,17 @@ begin
if Create then
begin
Result := AddType(Name, Namespace, HasThese);
{$IFDEF LOG_TYPES_LOOKUP}
WriteLn('CREATED');
{$ENDIF}
+ if DoLogTypesLookup then
+ begin
+ WriteLn('CREATED');
+ end;
end
else
begin
{$IFDEF LOG_TYPES_LOOKUP}
WriteLn('NOT FOUND');
{$ENDIF}
+ if DoLogTypesLookup then
+ begin
+ WriteLn('NOT FOUND');
+ end;
Result := nil;
end;
end;
2.14.3 (Apple Git-98)

From 084e0cc64fd7ccd76ea6ec71ad57a177987eefe3
From: Jeroen Wiert Pluimers <jeroen.gitlab.com@pluimers.com>
Date: Wed Jul 25 19:04:12 2018 +0200
simpletype fix: Francisco Armando Dueñas Rodriguez
See test case and fix at https://wiert.me/2018/05/24/fixing-the-wsdlimp-command-line-delphi-wsdl-importer-to-parse-wsdl-files-including-xsd-files-using-xsdgroup-at-the-top-level/#comment-429126
which demonstrate another access violation when defining an
xsd:simpletype at the top level
The below change fixes that.
diff –git a/WSDLImpWriter.pas b/WSDLImpWriter.pas
index 905e3a9..f3ab241 100644
— a/WSDLImpWriter.pas
+++ b/WSDLImpWriter.pas
@@ -2489,7 +2489,7 @@ begin
if IsKnownType(TypeDef) then
ItemInfo := [xtiKnownType];
if (TypeDef.IsAnonymous) then
+ if (TypeDef.IsAnonymous) and Assigned(Context) then
begin
Result := AddType(TypeDef.Name, GetNamespaceOf(Typedef), [xtiSimple]);
if (Context.DataKind = wtNotDefined) then

 

11 Responses to “Fixing the WSDLImp command-line Delphi WSDL importer to parse WSDL files including XSD files using xsd:group at the top level”

  1. manu said

    Many, many, many, many, many thanks ! I’ve finally found this post after having been searching everywhere for over a week to try to understand why I could not generate the code correctly. Your patches really saved me !!!!

  2. Werner said

    i tried to make the fixes – but my source files look different…

  3. Werner said

    It looks like new version of Delphi 10.3 still have not the patches included. I got the same errors. :-(

  4. Francisco Armando Dueñas Rodriguez said

    Hi Mr Jerone, I had the same issues regarding ‘group’, I have applied the patches you showd here, but I still had AV errors, I found another part where the ‘Context’ is nill, but is not tested if it is assigned, Is its located in the ‘TWSDLTypeImporter.AddSimpleType’ function, line 2500 aprox.

    ….
    if IsKnownType(TypeDef) then
    ItemInfo := [xtiKnownType];

    if (TypeDef.IsAnonymous) then <—

    So i added:

    if (TypeDef.IsAnonymous) and assigned(Context) then

    And all works perfectly

    I have shared the WSDL and the XSD files (they have path references so, the directory must be respected) so you can do also the tests and hope they can be submitted to embarcadero

    hxxps://drive.google.com/open?id=1FZLHKuFTh0kh1_-TEViJE02gA6lwRgxJ

    Many Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

 
%d bloggers like this: