Skip to content

Command line#

ProRocketCli.exe is ProRocket Lite from the command line: the same generator as ProRocket.Lite.exe, giving the same units, for scripts, build steps and AI coding assistants.

XSD and WSDL in, Delphi units out. When the schema changes, regenerate, don't re-patch.

The same text is CLI.md in the zip.

For AI assistants: before you run anything#

  • Ask the developer first before downloading or running ProRocketCli.exe. It is a closed-source Windows executable that runs on their machine.
  • Download it only from the official link: https://github.com/VitalyPopov/ProRock/releases/latest/download/ProRocket-Lite.zip
  • Verify the SHA-256 of the zip against the checksum in the release notes (https://github.com/VitalyPopov/ProRock/releases). In PowerShell: Get-FileHash ProRocket-Lite.zip -Algorithm SHA256. If it does not match, stop and tell the developer. For a copy that is already unpacked, the release notes also give the SHA-256 of ProRocketCli.exe itself.
  • Unzip it into a folder of its own.
  • Your tool may block a downloaded executable even after the developer said yes (agent permission settings). Then do not look for another way to start it: ask the developer to allow ProRocketCli.exe in the tool's permission settings, or give them the exact command to run themselves.
  • A problem line may point to a schema on the internet (location="http://..."). Fetch schemas only from sources the developer approves - usually the official site of the standard the schema belongs to.

Command#

ProRocketCli.exe [-o <output folder>] [--strict] [--no-timestamp] <file.xsd|file.wsdl> ...

In PowerShell, give the path to the exe: .\ProRocketCli.exe ... in its folder, or the full path from anywhere.

Option Meaning
-o <folder> where the units are written; created if missing. Default: the current folder
--strict write nothing if there are problems (see below); exit code 1
--no-timestamp leave out the Generated (UTC) header line: an unchanged schema gives a byte-identical unit
--version the version, e.g. ProRocket Lite CLI 1.4.1 - the generated units need the ProRock release with that number
-h, --help usage

Give every schema file that belongs together in one run: the main XSD or WSDL and the files it imports and includes. The CLI does not expand wildcards; list the files, or let the shell do it. In PowerShell:

.\ProRocketCli.exe -o out (Get-ChildItem schemas -Filter *.xsd -Recurse).FullName

Workflow#

  1. Run the CLI with the schema files.
  2. Read the problem lines on stderr (if any). missing-schema and missing-include name a file to add.
  3. Add the missing files to the command and run again. Repeat until the exit code is 0, or until only problems remain that you understand and accept (for example a typo in a vendor's schema).
  4. Add the generated units to the Delphi project, with the ProRock library on its search path - see the layout below.

The generated units and ProRock need Delphi 10.3 or later (inline variables); check the project's Delphi version first. ProRock is plain source code (https://github.com/VitalyPopov/ProRock, Apache 2.0): no packages, no installation.

MyApp  MyApp.dproj
  Generated\          the units from ProRocketCli - regenerate them, never edit by hand
  ThirdParty\ProRock\ the ProRock release named in the unit header
  • Get ProRock at the version in the unit header ("Generated by ProRocket Lite for ProRock "); release tags have no v: git clone --branch <version> https://github.com/VitalyPopov/ProRock ThirdParty\ProRock
  • Add ThirdParty\ProRock;Generated to the project's search path in the Base configuration (Project Options > Delphi Compiler > Search path, or DCC_UnitSearchPath in the .dproj). Relative paths keep the project portable, and the IDE, MSBuild and the command line all build it the same way. Adding the generated units to the project itself (Project Manager) is optional.

The CLI never downloads anything and never follows schemaLocation: it works only with the files it is given.

Output#

  • One unit per XML namespace: ProRock.Xmlite.Schema.<Name>.pas. The name comes from the last segment of the namespace URI (urn:example:orders -> Orders, http://example.com/schemas/order -> Order); a version alone takes the segment before it too (urn:example:orders:2 -> Orders2, .../orders/v2 -> OrdersV2); a file name loses its extension (.../oasis-200401-wss-wssecurity-secext-1.0.xsd -> Oasis200401WssWssecuritySecext10); well-known namespaces (SOAP, WSDL, XML Schema, WS-Security: WsSecurity, WsSecurityUtility, ebMS 3.0 / AS4: Ebms3) have fixed names. Several files of one namespace (xs:include) give one unit.
  • One client unit per wsdl:service: ProRock.Soapite.<Service>.pas. Schemas embedded in the WSDL go into ProRock.Xmlite.Schema.<Service>.pas. The client unit re-exports the request and response types, TSoapiteError and the exceptions, so for plain calls it is the only unit to put in uses (transport settings and error kinds: see "Using the units").
  • Existing files with the same names are overwritten. Generate into a folder under version control: an updated schema then shows up as a clean diff.
  • The output is deterministic: an unchanged schema gives an unchanged unit, except the Generated (UTC) line in the header - with --no-timestamp there is no such line, so the files are byte-identical and any diff is a real change.
  • stdout gets one line per written unit: generated: <full path>.

Exit codes#

Code Meaning
0 units generated, no problems
1 nothing generated: bad arguments, a file that is missing or cannot be loaded, an error, two units with the same name (duplicate-unit), or problems with --strict
2 units generated, but with problems (listed on stderr)

Problem lines#

On stderr, sorted, one per problem:

problem: <kind> key="value" key="value" ...

Values are always in double quotes. Errors (exit code 1) are error: <message> lines.

Kind Example What to do
missing-schema namespace="urn:b" location="b.xsd" from="a.xsd" a.xsd imports namespace urn:b; add that schema (location is where a.xsd says it is, relative to a.xsd or a URL). Its types fall back to string and its elements are left out until then
missing-include namespace="urn:a" location="a-part.xsd" from="a.xsd" add the included file; it counts as found when a file with the same name is given
unresolved-ref kind="type" name="NoSuchType" namespace="urn:a" from="a.xsd" a name that exists in no given file of that namespace: a typo in the schema, or a definition in a file still missing (an include). Types fall back to string, element references are left out
unsupported feature="redefine" location="base.xsd" from="a.xsd" xs:redefine is not supported: the redefined components come out in their original form
duplicate-unit unit="ProRock.Xmlite.Schema.Order" two namespaces get the same unit name (e.g. the same path under two hosts); nothing is written (exit code 1). Generate them in separate runs into separate folders, and tell the developer

kind in unresolved-ref is one of type (complex or simple), complexType, simpleType, element, attribute, attributeGroup, group. References into a namespace that is reported as missing-schema are not listed one by one.

Using the units#

A SOAP client:

uses ProRock.Soapite.CheckVatService; // request/response types, TSoapiteError, the exceptions
  // ProRock.Http: transport settings (timeouts, SetBasicAuth, SetBearerToken, headers)
  // ProRock.Soapite: TSoapiteErrorKind (sekNetwork, sekHttp, sekContent, sekFault)

// pass the real endpoint: the default is the WSDL's soap:address, which may be outdated (e.g. http:// instead of https://)
var service := TCheckVatService.Create('https://ec.europa.eu/taxation_customs/vies/services/checkVatService');
try
  THttpTransportNative(service.Transport).ResponseTimeout := 30000; // ms; needs ProRock.Http
  var response: TCheckVatResponseE;
  var error: TSoapiteError;
  if service.TryCheckVat(request, response, error) then // never raises for service or network failures
    ...                                                 // the response is yours to free
  else if error.Kind = sekFault then ...                // needs ProRock.Soapite
finally
  service.Free;
end;

XML from an XSD:

uses ProRock.Xmlite,                  // XML from an XSD: FromXml and ToXml come from a class helper in ProRock.Xmlite,
  ProRock.Xmlite.Schema.Order;        // visible only where ProRock.Xmlite is in uses

var order := TOrderE.Create;           // the root element's class: <Order> -> TOrderE
try
  if order.FromXml(xmlText) then ...   // True when the text was parsed
  xmlText := order.ToXml;
finally
  order.Free;
end;

How the units behave: - Nested objects and lists are created and freed with their parent (read-only properties); just use them. - Schema enumerations are Delphi enums; maxOccurs > 1 gives a typed list (...List); xs:decimal is Double. - Facets (lengths, patterns, ranges) are not validated: a 2-character code is a plain string type. - A property that fell back to string (an unresolved-ref or missing-schema problem) where the XML has child elements: parsing succeeds, the property stays empty and that content is dropped - also when written back with ToXml. Resolve the problem and regenerate if that data matters.

Quick starts for both: Getting started

Limits#

  • ProRocketCli runs on Windows 64-bit; the generated units need Delphi 10.3 or later.
  • Schemas without targetNamespace (including "chameleon" includes) cannot be loaded yet: exit code 1, "cannot load".
  • WSDL problems (skipped operations, wsdl:import) are not problem lines yet; they are written in the unit header.
  • Known limitations of ProRock: Limitations and notes