XSDCXX(1)

πŸ“¦
version 4.1.0 Β· 2 versions
, in epel 10, epel 9, fedora 43, fedora 44

XSDCXX(1) πŸ’–

General Commands Manual πŸŽ€

okay bestie, sit DOWN, hydrate, and get comfy, because we're about to read the manual for xsdcxx together and honestly? it's giving compiler-girlie excellence ✨ no cap.


🌸 NAME 🌸

xsdcxx β€” W3C XML Schema to C++ Compiler πŸ’…


πŸ¦‹ SYNOPSIS πŸ¦‹

xsdcxx command [ options ] file [ file ...]
xsdcxx help [ command ]
xsdcxx version

✨ DESCRIPTION ✨

So like, xsdcxx takes W3C XML Schema definitions and generates vocabulary-specific, statically-typed C++ mappings from them. Slay. πŸ’–

Which particular mapping you get is decided by the command you run. And every mapping has its own little pile of mapping-specific options that should show up β€” if you're using any β€” after the command. Order matters, bestie, we don't just be throwing flags around. πŸ™ˆ

Your input files should be W3C XML Schema definitions. And the exact set of files that come out the other end? That depends entirely on which mapping you picked and which options you passed. No two vibes are the same. 🌈


πŸ‘‘ COMMANDS πŸ‘‘

cxx-tree 🌳

Generates the C++/Tree mapping. For every input file shaped like name.xsd, you get these C++ files:

  • name.hxx β€” the header file πŸ’œ
  • name.ixx β€” the inline file, and it's only generated if you specified the --generate-inline option
  • name.cxx β€” the source file
  • name-fwd.hxx β€” the forward declaration file, and it's only generated if you specified the --generate-forward option

cxx-parser 🧚

Generates the C++/Parser mapping. For every input file shaped like name.xsd, you get these C++ files:

  • name-pskel.hxx β€” the parser skeleton header file
  • name-pskel.ixx β€” the parser skeleton inline file, generated only if you specified the --generate-inline option
  • name-pskel.cxx β€” the parser skeleton source file

And if you specified the --generate-noop-impl or --generate-print-impl option, you also get these extra sample implementation files:

  • name-pimpl.hxx β€” the parser implementation header file
  • name-pimpl.cxx β€” the parser implementation source file

And if you specified the --generate-test-driver option, you additionally get the name-driver.cxx test driver file. ✨

help 🫢

Prints usage information and then exits. And if you want the tea on one specific command, do:

xsdcxx help command

version πŸŽ€

Prints the version and exits. That's it, that's the whole job. Iconic.


πŸ’… OPTIONS πŸ’…

Heads up: command-specific options, if there are any, should appear after the corresponding command. Don't be putting them in the wrong place, bestie. 😭


🌟 common options 🌟

--std version

Tells the compiler which C++ standard the generated code should conform to. Valid values are c++98 (that's the default, babes) and c++11.

The C++ standard affects a bunch of different aspects of the generated code, and those are discussed in more detail in the various mapping-specific docs. But the overall vibe check? When C++11 is selected, the generated code relies on move semantics and uses std::unique_ptr instead of the deprecated std::auto_ptr. glow up. πŸ’…

When you're in C++11 mode, you normally don't need to do any extra steps beyond enabling C++11 in your C++ compiler, if it even requires that. The XSDCXX compiler will automatically add the necessary macro defines to the generated header files, and those switch the header-only XSDCXX runtime library (libxsd) over to C++11 mode. However β€” and this is the important part β€” if you include any of the XSDCXX runtime headers directly in your application (normally you just include the generated headers), then you'll need to define the XSD_CXX11 macro for your entire project. Don't forget. write it down. πŸ“

--char-type type

Generates code using the character type you provide instead of the default char. Valid values are char and wchar_t.

--char-encoding enc

Specifies the character encoding that should be used in the generated code.

Valid values for the char character type are utf8 (default), iso8859-1, lcp (Xerces-C++ local code page), and custom. If you pass custom as the value, then you'll need to include the transcoder implementation header for your encoding at the beginning of the generated header files (peep the --hxx-prologue option for that).

For the wchar_t character type, the only valid value is auto, and the encoding is automatically selected between UTF-16 and UTF-32/UCS-4, depending on the size of the wchar_t type. she chooses for you. πŸ¦‹

--output-dir dir

Writes the generated files to dir instead of to the current directory.

--generate-inline

Generates simple functions inline. This option triggers creation of the inline file. ✨

--generate-xml-schema

Generates a C++ header file as if the schema being compiled defines the XML Schema namespace. For the C++/Tree mapping, the resulting file will contain definitions for all XML Schema built-in types. For the C++/Parser mapping, the resulting file will contain definitions for all the parser skeletons and implementations corresponding to the XML Schema built-in types.

Now listen: the schema file you hand to the compiler need not exist β€” it's only used to derive the name of the resulting header file. And you can use the --extern-xml-schema option to include this file in the generated files for other schemas.

--extern-xml-schema file

Includes a header file derived from file instead of generating the XML Schema namespace mapping inline. The file you provide need not exist β€” it's only used to derive the name of the included header file. Use the --generate-xml-schema option to generate this header file.

--namespace-map xns=cns

Maps the XML Schema namespace xns to the C++ namespace cns. Repeat this option to specify a mapping for more than one XML Schema namespace.

For example, this option:

--namespace-map http://example.com/foo/bar=foo::bar

will map the http://example.com/foo/bar XML Schema namespace to the foo::bar C++ namespace. cute. πŸ’œ

--namespace-regex regex

Adds regex to the list of regular expressions used to translate XML Schema namespace names into C++ namespace names. regex is a Perl-like regular expression in the form /pattern/replacement/. Any character can be used as a delimiter instead of /. Heads up though: escaping of the delimiter character in pattern or replacement is not supported. 😬

All the regular expressions are pushed into a stack, with the last specified expression considered first. The first match that succeeds is the one that gets used.

Regular expressions are applied to a string in the form:

filename namespace

For example, if you have file hello.xsd with namespace http://example.com/hello and you run xsd on this file, then the string in question will be:

hello.xsd. http://example.com/hello

For the built-in XML Schema namespace, the string is:

XMLSchema.xsd http://www.w3.org/2001/XMLSchema

Then the following three steps are performed for each regular expression until the match is found:

  1. The expression is applied, and if the result is empty, the next expression is considered.
  2. All / are replaced with ::.
  3. The result is verified to be a valid C++ scope name (e.g., foo::bar). If this test succeeds, the result is used as a C++ namespace name.

As an example, the following expression maps XML Schema namespaces in the form http://example.com/foo/bar to C++ namespaces in the form foo::bar:

%.* http://example.com/(.+)%$1%

See also the REGEX AND SHELL QUOTING section below. πŸ‘€

--namespace-regex-trace

Traces the process of applying regular expressions specified with the --namespace-regex option. Use this option to find out why your regular expressions don't do what you expected them to do. (we've all been there bestie, no shame 🫢)

--reserved-name n[=r]

Adds the name n to the list of names that should not be used as identifiers. The name can optionally be followed by = and the replacement name r that should be used instead. And FYI: all the C++ keywords are already in this list. πŸ’€

--include-with-brackets

Uses angle brackets (<>) instead of quotes ("") in the generated #include directives.

--include-prefix prefix

Adds prefix to the generated #include directive paths.

For example, if you had the following import element in your schema:

<import namespace="..." schemaLocation="base.xsd"/>

and compiled this fragment with --include-prefix schemas/, then the include directive in the generated code would be:

#include "schemas/base.hxx"

slay. ✨

--include-regex regex

Adds regex to the list of regular expressions used to transform #include directive paths. regex is a Perl-like regular expression in the form /pattern/replacement/. Any character can be used as a delimiter instead of /. And again β€” escaping of the delimiter character in pattern or replacement is not supported. πŸ™ˆ

All the regular expressions are pushed into a stack, with the last specified expression considered first. The first match that succeeds is the one that gets used.

As an example, the following expression transforms paths in the form schemas/foo/bar to paths in the form generated/foo/bar:

%schemas/(.+)%generated/$1%

See also the REGEX AND SHELL QUOTING section below. πŸ‘‘

--include-regex-trace

Traces the process of applying regular expressions specified with the --include-regex option. Use this option to find out why your regular expressions don't do what you expected them to do.

--guard-prefix prefix

Adds prefix to the generated header inclusion guards. The prefix is transformed to upper case, and characters that are illegal in a preprocessor macro name are replaced with underscores. If this option is not specified, then the directory part of the input schema file is used as a prefix.

--hxx-suffix suffix

Uses the provided suffix instead of the default .hxx to construct the name of the header file. Note that this suffix is also used to construct names of header files corresponding to included/imported schemas. πŸŽ€

--ixx-suffix suffix

Uses the provided suffix instead of the default .ixx to construct the name of the inline file.

--cxx-suffix suffix

Uses the provided suffix instead of the default .cxx to construct the name of the source file.

--fwd-suffix suffix

Uses the provided suffix instead of the default -fwd.hxx to construct the name of the forward declaration file.

--hxx-regex regex

Uses the provided expression to construct the name of the header file. regex is a Perl-like regular expression in the form /pattern/replacement/. Note that this expression is also used to construct names of header files corresponding to included/imported schemas. See also the REGEX AND SHELL QUOTING section below. 🌸

  • --ixx-regex regex β€” this is how you name your inline file, bestie πŸ’…. You hand over a Perl-like regular expression shaped like /pattern/replacement/ and it does its thing. Peep the REGEX AND SHELL QUOTING section below for the tea.
  • --cxx-regex regex β€” same energy, but for naming the source file. Format is /pattern/replacement/, Perl-like, no cap. Check REGEX AND SHELL QUOTING below.
  • --fwd-regex regex β€” and this one names the forward declaration file ✨. Again: Perl-like /pattern/replacement/. REGEX AND SHELL QUOTING section below has the deets.
  • --hxx-prologue text β€” drops text right at the beginning of the header file. Like, first thing in the door πŸšͺ.
  • --ixx-prologue text β€” same but it's the beginning of the inline file 🌸.
  • --cxx-prologue text β€” beginning of the source file, you already know the vibe 🫢.
  • --fwd-prologue text β€” beginning of the forward declaration file. Slay.
  • --prologue text β€” the fallback bestie: it drops text at the beginning of every generated file that doesn't already have its own file-specific prologue πŸ‘‘
  • --hxx-epilogue text β€” inserts text at the end of the header file. Outro energy πŸ’«.
  • --ixx-epilogue text β€” end of the inline file. Periodt.
  • --cxx-epilogue text β€” end of the source file πŸŽ€.
  • --fwd-epilogue text β€” end of the forward declaration file ✨.
  • --epilogue text β€” the fallback again, but for endings: sticks text at the end of each generated file that has no file-specific epilogue πŸ’œ.
  • --hxx-prologue-file file β€” takes the content of file and puts it at the beginning of the header file πŸ“„.
  • --ixx-prologue-file file β€” content of file, beginning of the inline file 🌸.
  • --cxx-prologue-file file β€” content of file, beginning of the source file.
  • --fwd-prologue-file file β€” content of file, beginning of the forward declaration file.
  • --prologue-file file β€” fallback file version: content of file goes at the beginning of every generated file with no file-specific prologue file 🫢.
  • --hxx-epilogue-file file β€” content of file, end of the header file.
  • --ixx-epilogue-file file β€” content of file, end of the inline file πŸ’….
  • --cxx-epilogue-file file β€” content of file, end of the source file.
  • --fwd-epilogue-file file β€” content of file, end of the forward declaration file.
  • --epilogue-file file β€” fallback: content of file goes at the end of each generated file with no file-specific epilogue file ✨.
  • --export-symbol symbol β€” inserts symbol everywhere those DLL export/import control statements (__declspec(dllexport/dllimport)) need to show up πŸ‘‘.
  • --export-xml-schema β€” exports/imports types in the XML Schema namespace using the export symbol you gave to --export-symbol. There's a macro, XSD_NO_EXPORT, that you can use to omit this code during C++ compilation β€” handy if you wanna use the same generated code across multiple platforms 🌈.
  • --export-maps β€” exports the polymorphism support maps out of a Win32 DLL that this generated code lives in. This matters when your type hierarchy is split across several DLLs, because otherwise each DLL gets its own little set of maps (messy πŸ’€). In that situation: compile the generated code for the DLL holding the base types and/or substitution group heads with this option, and compile all the other DLLs' generated code with --import-maps. This option is only valid together with --generate-polymorphic. And yes, XSD_NO_EXPORT can omit this code during C++ compilation β€” useful for reusing the same generated code across multiple platforms 🫢.
  • --import-maps β€” imports the polymorphism support maps into a Win32 DLL or executable that this generated code is linked into. Scroll up to --export-maps for the full story πŸ“–. This option is only valid together with --generate-polymorphic. XSD_NO_EXPORT can omit this code during C++ compilation, which may be useful if you want the same generated code across multiple platforms ✨.
  • --generate-dep β€” generates make dependency information. This triggers creation of the .d file holding the dependencies of the generated files on the main schema file plus every schema file it includes/imports, transitively πŸ”—. That dependency file then normally gets included into the main makefile so you get automatic dependency tracking. Big slay.
Heads up bestie: automatic dependency generation is not supported in file-per-type mode (--file-per-type) 😭. In that case all the generated files come out of a single compiler invocation and depend on all the schemas. So it's easier to set that dependency up manually, maybe with a little help from the --file-list* options.
  • --generate-dep-only β€” generates make dependency information, and only that. Nothing else. Iconic minimalism πŸ’….
  • --dep-phony β€” generates phony targets for included/imported schema files, making each one depend on nothing. These dummy rules work around make errors that happen when someone deletes schema files without also updating the dependency file to match πŸ™ˆ.
  • --dep-target target β€” changes the target of the dependency rule. By default it contains all the generated C++ files plus the dependency file itself, with no directory prefixes. Need multiple targets? Pass them as one space-separated argument, or just repeat this option multiple times πŸ”.
  • --dep-suffix suffix β€” use suffix instead of the default .d when constructing the dependency file's name.
  • --dep-regex regex β€” use this expression to build the dependency file's name. regex is a Perl-like regular expression in the form /pattern/replacement/. See the REGEX AND SHELL QUOTING section below 🌸.
  • --disable-warning warn β€” turns off the warning with id warn. If you pass all as the warning id, then every single warning is disabled πŸ’€.
  • --options-file file β€” reads extra options from file πŸ“„. Each option should sit on its own line, optionally followed by a space and an option value. Empty lines and lines starting with # are ignored. Option values can be wrapped in double (") or single (') quotes to preserve leading and trailing whitespace, and to specify empty values. If the value itself has leading or trailing quotes, wrap it in an extra pair of quotes, like '"x"'. Non-leading and non-trailing quotes are just interpreted as part of the option value, fr fr.

The semantics of giving options in a file are equivalent to giving the same set of options in the same order on the command line, at the exact point where --options-file is specified β€” except you don't need the shell escaping and quoting ✨. You can repeat this option to specify more than one options file.

  • --show-sloc β€” shows the number of generated physical source lines of code (SLOC) πŸ“Š.
  • --sloc-limit num β€” checks that the number of generated physical source lines of code (SLOC) does not exceed num. Vibe check on your line count 🫢.
  • --proprietary-license β€” says the generated code is licensed under a proprietary license instead of the GPL πŸ“œ.
  • --custom-literals file β€” loads custom XML-string-to-C++-literal mappings from file. This is a whole mechanism for when you're using a custom character encoding and some strings in your schemas β€” element/attribute names, enumeration values, that kinda thing β€” contain non-ASCII characters 🌈. In that case you need to supply a custom mapping to C++ literals for those strings. The format of this file is specified in the custom-literals.xsd XML Schema file, which lives in the documentation directory πŸ“.
  • --preserve-anonymous β€” preserves anonymous types. By default, anonymous types get automatically named with names derived from their enclosing elements/attributes. But because the mappings this compiler implements need all types to be named, this option is only useful if you wanna make sure your schemas don't have anonymous types πŸ‘‘.
  • --show-anonymous β€” shows elements and attributes that are of anonymous types. This option only makes sense together with --preserve-anonymous, iykyk πŸ’….
  • --anonymous-regex regex β€” adds regex to the list of regular expressions used to derive names for anonymous types from the enclosing attributes/elements. regex is a Perl-like regular expression in the form /pattern/replacement/. Any character can be used as a delimiter instead of /. Escaping of the delimiter character in pattern or replacement is not supported πŸ™ˆ.

All the regular expressions get pushed into a stack, with the last specified expression considered first. The first match that succeeds is the one that's used ✨. Regular expressions are applied to a string in the form

filename namespace xpath

For instance:

hello.xsd http://example.com/hello element

hello.xsd http://example.com/hello type/element

As an example, the following expression makes all the derived names start with capital letters πŸ”€. This could be useful when your naming convention requires type names to start with capital letters:

%.* .* (.+/)*(.+)%\u$2%

See also the REGEX AND SHELL QUOTING section below 🌸.

  • --anonymous-regex-trace β€” traces the whole process of applying the regular expressions you specified with --anonymous-regex πŸ”. Use this when your regexes aren't doing what you expected them to do β€” it's literally the "why is this not working" button, bestie 😭.
  • --location-map ol=nl β€” bestie, this maps the original schema location ol that's sitting in your XML Schema include or import elements over to a new schema location nl. Want more than one mapping? Just repeat the option, one per map, no cap. For example, this bad boy maps the http://example.com/foo.xsd URL to the local file foo.xsd:
--location-map http://example.com/foo.xsd=foo.xsd
  • --location-regex regex β€” adds regex to the list of regular expressions used to map schema locations that show up in XML Schema include or import elements. regex is a Perl-like regular expression shaped like /pattern/replacement/. Any character can be the delimiter instead of /. Escaping the delimiter character in pattern or replacement is not supported β€” just don't, okay? All the regular expressions get pushed onto a stack, and the one you specified last is considered first. The first match that succeeds is the one that gets used. Periodt.

Example time πŸŽ€ β€” this expression maps URL locations in the form http://example.com/foo/bar.xsd to local files in the form bar.xsd:

%http://.+/(.+)%$1%

Also go peek at the REGEX AND SHELL QUOTING section below. iykyk.

  • --location-regex-trace β€” traces the whole process of applying the regular expressions you gave with --location-regex. Use this when your regexes are acting brand new and you need to find out why they don't do what you expected them to do. Detective mode fr fr πŸ”
  • --file-per-type β€” generates a separate set of C++ files for each type defined in the XML Schema. Heads up: in this mode you only need to compile the root schema(s) and the code will be generated for all the included and imported schemas. This compilation mode is mainly the move when some of your schemas can't be compiled separately or have cyclic dependencies that involve type inheritance. Other options that vibe with this mode: --type-file-regex, --schema-file-regex, --fat-type-file, and --file-list.
  • --type-file-regex regex β€” adds regex to the list of regular expressions used to translate type names to file names when --file-per-type is specified. regex is a Perl-like regular expression shaped like /pattern/replacement/. Any character can be the delimiter instead of /. Escaping the delimiter character in pattern or replacement is not supported. All the regular expressions get pushed onto a stack, last one specified is considered first, first match that succeeds wins. The regular expressions get applied to a string in the form:
namespace type-name

So like, this expression maps type foo that's defined in the http://example.com/bar namespace to file name bar-foo:

%http://example.com/(.+) (.+)%$1-$2%

And yeah β€” check the REGEX AND SHELL QUOTING section below too ✨

  • --type-file-regex-trace β€” traces the process of applying the regular expressions you specified with --type-file-regex. Use it to figure out why your regexes aren't doing what you expected. We've all been there 😭
  • --schema-file-regex regex β€” adds regex to the list of regular expressions used to translate schema file names when --file-per-type is specified. regex is a Perl-like regular expression shaped like /pattern/replacement/. Any character can be the delimiter instead of /. Escaping the delimiter character in pattern or replacement is not supported. All the regular expressions get pushed onto a stack with the last one specified considered first, and the first match that succeeds is used. The regular expressions get applied to the absolute filesystem path of a schema file, and the result β€” directory part and all, if there is one β€” is used to derive the #include directive paths as well as the generated C++ file paths. This option, along with --type-file-regex, is mainly useful to drop your generated files into subdirectories or to resolve file name conflicts. Slay πŸ’…

For example, this expression maps schema files in the foo/1.0.0/ subdirectory to files in the foo/ subdirectory. As a result, the #include directive paths for such schemas will be in the foo/schema.hxx form and the generated C++ files will be placed into the foo/ subdirectory:

%.*/foo/1.0.0/(.+)%foo/$1%

And also see the REGEX AND SHELL QUOTING section below πŸ¦‹

  • --schema-file-regex-trace β€” traces the process of applying the regular expressions specified with --schema-file-regex. Use this option to find out why your regular expressions don't do what you expected them to do. No judgment, bestie πŸ™ˆ
  • --fat-type-file β€” generates code corresponding to global elements into type files instead of schema files when the --type-file-regex option is specified. This one's mainly useful when you're trying to minimize the amount of object code linked to an executable by packaging compiled generated code into a static (archive) library. Lean and mean ✨
  • --file-list file β€” writes a list of generated C++ files to file. This option is primarily useful in the file-per-type compilation mode (--file-per-type) to create a list of generated C++ files β€” for example, as a makefile fragment. Very main character of you.
  • --file-list-prologue text β€” inserts text at the beginning of the file list. As a convenience, all occurrences of the \n character sequence in text get replaced with new lines. You can use this, for example, to assign the generated file list to a makefile variable. πŸŽ€
  • --file-list-epilogue text β€” inserts text at the end of the file list. As a convenience, all occurrences of the \n character sequence in text get replaced with new lines.
  • --file-list-delim text β€” delimits file names written to the file list with text instead of new lines. As a convenience, all occurrences of the \n character sequence in text get replaced with new lines.

πŸ’– cxx-tree command options πŸ’–

  • --generate-polymorphic β€” generates polymorphism-aware code. Specify this option if you use substitution groups or xsi:type. Then use the --polymorphic-type or --polymorphic-type-all option to say which type hierarchies are polymorphic. πŸ‘‘
  • --polymorphic-type type β€” indicates that type is a root of a polymorphic type hierarchy. The compiler can often automatically figure out which types are polymorphic based on the substitution group declarations. But you may need this option if you're not using substitution groups, or if the substitution groups are defined in another schema. You need to specify this option when compiling every schema file that references type. The type argument is an XML Schema type name that can optionally be qualified with a namespace in the namespace#name form.
  • --polymorphic-type-all β€” indicates that all types should be treated as polymorphic. All of them. Every single one. Periodt.
  • --polymorphic-plate num β€” specifies the polymorphic map plate the generated code should register on. This functionality is mainly useful to segregate multiple schemas that define the same polymorphic types.
  • --ordered-type type β€” indicates that element order in type is significant. An example would be a complex type with unbounded choice as a content model where the element order in XML has application-specific semantics. For ordered types, the compiler generates a special container data member plus a corresponding set of accessors and modifiers that are used to capture the order of elements and, for mixed content, of text. ✨

The type argument is an XML Schema type name that can optionally be qualified with a namespace in the namespace#name form. Also note β€” you'll need to specify this option when compiling every schema file that has other ordered types derived from this type.

  • --ordered-type-derived β€” automatically treats types derived from ordered bases as also ordered. This is primarily useful if you'd like to be able to iterate over the complete content using the content order container. 🌈
  • --ordered-type-mixed β€” automatically treats complex types with mixed content as ordered.
  • --ordered-type-all β€” indicates that element order in all types is significant. All of them bestie.
  • --order-container type β€” specifies a custom class template that should be used as a container for the content order in ordered types instead of the default std::vector. See --ordered-type for more info on ordered types. This option is primarily useful if you need to perform more complex lookups in the content order container β€” for example by element id. In that case, a container like Boost multi-index may be more convenient. Note that if you're using a custom container, you'll also most likely need to include the relevant headers using the --hxx-prologue* options. 🧚
  • --generate-serialization β€” generates serialization functions. Serialization functions convert the object model back to XML. The glow up cycle πŸ’«
  • --generate-ostream β€” generates ostream insertion operators (operator<<) for generated types. This lets you easily print a fragment or the whole object model for debugging or logging. Chef's kiss for debugging fr fr.
  • --generate-doxygen β€” generates documentation comments suitable for extraction by the Doxygen documentation system. Documentation from annotations is added to the comments if it's present in the schema. πŸ“
  • --generate-comparison β€” generates comparison operators (operator== and operator!=) for complex types. Comparison is performed member-wise. Iconic.
  • --generate-default-ctor β€” generates default constructors even for types that have required members. Required members of an instance constructed using such a constructor are not initialized, and accessing them results in undefined behavior. So like… be careful bestie, that's genuinely dangerous πŸ’€
  • --generate-from-base-ctor β€” generates constructors that expect an instance of a base type followed by all required members.
  • --suppress-assignment β€” suppresses the generation of copy assignment operators for complex types. If you specify this option, the copy assignment operators for such types are declared private and left unimplemented. 🚫
  • --generate-detach β€” bestie, this one generates detach functions for required elements and attributes πŸ’…. For optional and sequence cardinalities, the detach functions are already provided by the respective containers, so no worries there. What do these lil functions even do? They let you move sub-trees around in the object model β€” either within the same tree or between different trees 🌈. Slay.
  • --generate-wildcard β€” generates accessors and modifiers plus parsing and serialization code for XML Schema wildcards (any and anyAttribute) ✨. Any XML content matched by wildcards gets presented as DOM fragments. > Heads up queen: you need to initialize the Xerces-C++ runtime if you're using this option 🫢.
  • --generate-any-type β€” extracts and stores the content of the XML Schema anyType type as a DOM fragment πŸŽ€. > Same deal, bestie: initialize the Xerces-C++ runtime if you use this one πŸ’–.
  • --generate-insertion os β€” generates data representation stream insertion operators for the os output stream type πŸ”₯. Repeat this option if you wanna specify more than one stream type, no cap. The ACE CDR stream (ACE_OutputCDR) and RPC XDR are recognized by the compiler and the necessary #include directives get generated automatically β€” iconic ✨. For custom stream types, use the --hxx-prologue* options to provide the necessary declarations.
  • --generate-extraction is β€” generates data representation stream extraction constructors for the is input stream type πŸ’œ. Repeat this option to specify more than one stream type. The ACE CDR stream (ACE_InputCDR) and RPC XDR are recognized by the compiler and the necessary #include directives are automatically generated πŸ™ˆ. For custom stream types, use the --hxx-prologue* options to provide the necessary declarations.
  • --generate-forward β€” generates a separate header file with forward declarations for the types being generated 🌸.
  • --suppress-parsing β€” suppresses the generation of the parsing functions and constructors 😴. Use this option to reduce the size of the generated code when parsing from XML is just not needed.
  • --generate-element-type β€” generates types instead of parsing and serialization functions for root elements πŸ‘‘. This is primarily useful to distinguish object models with the same root type but with different root elements. iykyk.
  • --generate-element-map β€” generates a root element map that allows uniform parsing and serialization of multiple root elements πŸ¦‹. > This option is only valid together with --generate-element-type, bestie. Don't try it alone πŸ’€.
  • --generate-intellisense β€” generates workarounds for IntelliSense bugs in Visual Studio 2005 (8.0) 😭. When this option is used, the resulting code is slightly more verbose. IntelliSense in Visual Studio 2008 (9.0) and later does not require these workarounds, periodt. Support for IntelliSense in Visual Studio 2003 (7.1) is improved with this option but is still incomplete πŸ™ˆ.
  • --omit-default-attributes β€” omits attributes with default and fixed values from serialized XML documents ✨.
  • --type-naming style β€” specify the type naming convention that should be used in the generated code πŸ’…. Valid styles are knr (default), ucc, and java. See the NAMING CONVENTION section below for more info πŸŽ€.
  • --function-naming style β€” specify the function naming convention that should be used in the generated code 🌈. Valid styles are knr (default), lcc, and java. See the NAMING CONVENTION section below for more.
  • --type-regex regex β€” add regex to the list of regular expressions used to translate XML Schema type names to C++ type names ⭐. See the NAMING CONVENTION section below.
  • --accessor-regex regex β€” add regex to the list of regular expressions used to translate XML Schema names of elements/attributes to C++ accessor function names πŸ’–. See the NAMING CONVENTION section below.
  • --one-accessor-regex regex β€” add regex to the list of regular expressions used to translate XML Schema names of elements/attributes with cardinality one to C++ accessor function names πŸŽ€. See the NAMING CONVENTION section below.
  • --opt-accessor-regex regex β€” add regex to the list of regular expressions used to translate XML Schema names of elements/attributes with cardinality optional to C++ accessor function names πŸ’œ. See the NAMING CONVENTION section below.
  • --seq-accessor-regex regex β€” add regex to the list of regular expressions used to translate XML Schema names of elements/attributes with cardinality sequence to C++ accessor function names πŸ”₯. See the NAMING CONVENTION section below.
  • --modifier-regex regex β€” add regex to the list of regular expressions used to translate XML Schema names of elements/attributes to C++ modifier function names ✨. See the NAMING CONVENTION section below.
  • --one-modifier-regex regex β€” add regex to the list of regular expressions used to translate XML Schema names of elements/attributes with cardinality one to C++ modifier function names πŸ’…. See the NAMING CONVENTION section below.
  • --opt-modifier-regex regex β€” add regex to the list of regular expressions used to translate XML Schema names of elements/attributes with cardinality optional to C++ modifier function names πŸ¦‹. See the NAMING CONVENTION section below.
  • --seq-modifier-regex regex β€” add regex to the list of regular expressions used to translate XML Schema names of elements/attributes with cardinality sequence to C++ modifier function names 🌸. See the NAMING CONVENTION section below.
  • --parser-regex regex β€” add regex to the list of regular expressions used to translate XML Schema element names to C++ parsing function names πŸ‘‘. See the NAMING CONVENTION section below.
  • --serializer-regex regex β€” add regex to the list of regular expressions used to translate XML Schema element names to C++ serialization function names ⭐. See the NAMING CONVENTION section below.
  • --const-regex regex β€” add regex to the list of regular expressions used to translate XML Schema-derived names to C++ constant names πŸŽ€. See the NAMING CONVENTION section below.
  • --enumerator-regex regex β€” add regex to the list of regular expressions used to translate XML Schema enumeration values to C++ enumerator names πŸ’–. See the NAMING CONVENTION section below.
  • --element-type-regex regex β€” add regex to the list of regular expressions used to translate XML Schema element names to C++ element type names 🌈. See the NAMING CONVENTION section below.
  • --name-regex-trace β€” traces the process of applying regular expressions specified with the name transformation options πŸ”. Use this option to find out why your regular expressions don't do what you expected them to do β€” we've all been there bestie 😭.
  • --root-element-first β€” treats only the first global element as a document root 🌸. By default, all global elements are considered document roots.
  • --root-element-last β€” treats only the last global element as a document root πŸ¦‹. By default, all global elements are considered document roots.
  • --root-element-all β€” treats all global elements as document roots πŸ‘‘. This is the default behavior, periodt. By explicitly specifying this option you can suppress the warning that is issued if more than one global element is defined πŸ’….
  • --root-element-none β€” do not treat any global elements as document roots πŸ’€. By default, all global elements are considered document roots.
  • --root-element element β€” treat only element as a document root ✨. Repeat this option to specify more than one root element.
  • --custom-type map β€” use a custom C++ type instead of the generated class πŸ’œ. The map argument is in the form name[=type[/base]], where name is a type name as defined in XML Schema and type is a C++ type name that should be used instead. If type is not present or empty then the custom type is assumed to have the same name and be defined in the same namespace as the generated class would have. If base is specified then the generated class is still generated but with that name 🌈.
  • --custom-type-regex regex β€” use custom C++ types instead of the generated classes πŸŽ€. The regex argument is in the form /name-pat/[type-sub/[base-sub/]], where name-pat is a regex pattern that will be matched against type names as defined in XML Schema and type-sub is a C++ type name substitution that should be used instead. If type-sub is not present or its substitution results in an empty string then the custom type is assumed to have the same name and be defined in the same namespace as the generated class would have. If base-sub is present and its substitution results in a non-empty string then the generated class is still generated but with the result of this substitution as its name. The pattern and substitutions are in the Perl regular expression format ✨. See also the REGEX AND SHELL QUOTING section below.
  • --parts num β€” split generated source code into num parts πŸ“. This is useful when translating large, monolithic schemas and a C++ compiler is not able to compile the resulting source code at once (usually due to insufficient memory) 😭.
  • --parts-suffix suffix β€” use suffix instead of the default '-' to separate the file name from the part number πŸŽ€.

πŸ› οΈ cxx-parser command options πŸ› οΈ

  • --type-map mapfile β€” read XML Schema to C++ type mapping information from mapfile πŸ—ΊοΈ. Repeat this option to specify several type maps. Type maps are considered in order of appearance and the first match is used, periodt. By default all user-defined types are mapped to void πŸ’€. See the TYPE MAP section below for more information.
  • --xml-parser parser β€” use parser as the underlying XML parser πŸ”₯. Valid values are xerces for Xerces-C++ (default) and expat for Expat ✨.
  • --generate-validation β€” bestie this one makes the compiler spit out validation code. The validation code (aka the "perfect parser" ✨) makes sure your instance documents actually conform to the schema. And here's the tea: validation code gets generated by default whenever the underlying XML parser you picked is non-validating, like expat. So if you're on expat you already have it, no cap.
  • --suppress-validation β€” the opposite vibe πŸ’… it stops the validation code from being generated at all. And this is the default when your selected underlying XML parser is a validating one, like xerces. So xerces users, you're already suppressing, periodt.
  • --generate-polymorphic β€” generates code that's aware of polymorphism, slay πŸ¦‹ use this option if you're working with substitution groups or xsi:type. If that's your situation, this is the one, fr fr.
  • --generate-noop-impl β€” makes a sample parser implementation that does literally nothing (no operation, hence the name 🫠). The idea is you take that empty little sample and fill it in with your own application-specific code. For an input file shaped like name.xsd, this option triggers the generation of two extra C++ files in the form: name-pimpl.hxx (the parser implementation header file) and name-pimpl.cxx (the parser implementation source file). Two files, one vibe. πŸŽ€
  • --generate-print-impl β€” same energy as above but instead of nothing, this sample parser implementation prints the XML data to STDOUT 🌈 For an input file in the form name.xsd this option triggers the generation of two additional C++ files in the form: name-pimpl.hxx (parser implementation header file) and name-pimpl.cxx (parser implementation source file).
  • --generate-test-driver β€” gives you a test driver for that sample parser implementation you just made πŸ‘‘ For an input file in the form name.xsd this option triggers the generation of one additional C++ file in the form name-driver.cxx. That's the whole thing.
  • --force-overwrite β€” forces overwriting of the existing implementation and test driver files.
⚠️ okay listen, use this option ONLY if you do not mind losing the changes you've made in your sample implementation or test driver files. It will not hesitate. It will not warn you twice. It's giving ruthless. 😭
  • --root-element-first β€” tells the compiler that the first global element is the document root 🌱 This info gets used to generate the test driver for the sample implementation.
  • --root-element-last β€” tells the compiler that the last global element is the document root πŸ“ Same deal, this info is used to generate the test driver for the sample implementation.
  • --root-element element β€” lets you just say it out loud: element is the document root, thank you very much πŸ’… And yep, this info is used to generate the test driver for the sample implementation.
  • --skel-type-suffix suffix β€” use the suffix you provide instead of the default _pskel when constructing the names of the generated parser skeletons. Customize away ✨
  • --skel-file-suffix suffix β€” use the suffix you provide instead of the default -pskel when constructing the names of the generated parser skeleton files. πŸŽ€
  • --impl-type-suffix suffix β€” use the suffix you provide instead of the default _pimpl when constructing the names of the parser implementations for the built-in XML Schema types, plus the sample parser implementations too. Two birds, one flag πŸ¦‹
  • --impl-file-suffix suffix β€” use the suffix you provide instead of the default -pimpl when constructing the names of the generated sample parser implementation files. 🫢

🌸 NAMING CONVENTION 🌸

So the compiler can be told to use a particular naming convention in the generated code β€” and bestie, you have options. A whole bunch of widely-used conventions can be picked with the --type-naming and --function-naming options. And if you want something fully custom, you can get there with the --type-regex, --accessor-regex, --one-accessor-regex, --opt-accessor-regex, --seq-accessor-regex, --modifier-regex, --one-modifier-regex, --opt-modifier-regex, --seq-modifier-regex, --parser-regex, --serializer-regex, --const-regex, --enumerator-regex, and --element-type-regex options. That's a lot of regexes and honestly? iconic.

The --type-naming option specifies the convention that should be used for naming C++ types. Possible values for this option are knr (default), ucc, and java. The knr value (stands for K&R) means the standard, lower-case naming convention with the underscore used as a word delimiter, for example: foo, foo_bar. The ucc value (stands for upper-camel-case) and the java value are synonyms for the same naming convention where the first letter of each word in the name is capitalized, for example: Foo, FooBar. πŸ’–

Similarly, the --function-naming option specifies the convention that should be used for naming C++ functions. Possible values for this option are knr (default), lcc, and java. The knr value (stands for K&R) means the standard, lower-case naming convention with the underscore used as a word delimiter, for example: foo(), foo_bar(). The lcc value (stands for lower-camel-case) means a naming convention where the first letter of each word except the first is capitalized, for example: foo(), fooBar(). The java naming convention is similar to the lower-camel-case one except that accessor functions are prefixed with get, modifier functions are prefixed with set, parsing functions are prefixed with parse, and serialization functions are prefixed with serialize, for example: getFoo(), setFooBar(), parseRoot(), serializeRoot(). Chef's kiss, honestly 🧚

Now, important note, don't skip this: the naming conventions specified with the --type-naming and --function-naming options perform only limited transformations on the names that come from the schema in the form of type, attribute, and element names. In other words, to get consistent results, your schemas should follow a similar naming convention as the one you would like to have in the generated code. Alternatively, you can use the --*-regex options (discussed below) to perform further transformations on the names that come from the schema. Lowkey the schema is doing half the work here, just so you know πŸ‘€

The --type-regex, --accessor-regex, --one-accessor-regex, --opt-accessor-regex, --seq-accessor-regex, --modifier-regex, --one-modifier-regex, --opt-modifier-regex, --seq-modifier-regex, --parser-regex, --serializer-regex, --const-regex, --enumerator-regex, and --element-type-regex options let you specify extra regular expressions for each name category, on top of the predefined set that gets added depending on the --type-naming and --function-naming options. Expressions you give with the --*-regex options are evaluated prior to any predefined expressions. This lets you selectively override some or all of the predefined transformations. And when you're debugging your own expressions, it's often useful to see which expressions match which names β€” the --name-regex-trace option lets you trace the whole process of applying regular expressions to names. Debugging era πŸ”βœ¨

The value for the --*-regex options should be a perl-like regular expression in the form /pattern/replacement/. Any character can be used as a delimiter instead of /. Escaping of the delimiter character in pattern or replacement is not supported. All the regular expressions for each category are pushed into a category-specific stack, with the last specified expression considered first. The first match that succeeds is used. For the --one-accessor-regex (accessors with cardinality one), --opt-accessor-regex (accessors with cardinality optional), and --seq-accessor-regex (accessors with cardinality sequence) categories, the --accessor-regex expressions are used as a fallback. For the --one-modifier-regex, --opt-modifier-regex, and --seq-modifier-regex categories, the --modifier-regex expressions are used as a fallback. And for the --element-type-regex category, the --type-regex expressions are used as a fallback. Stack behavior, first match wins, fallbacks everywhere β€” it's giving very structured 🌈

The type name expressions (--type-regex) are evaluated on the name string that has the following format:

[namespace  ]name[,name][,name][,name]

The element type name expressions (--element-type-regex), effective only when the --generate-element-type option is specified, are evaluated on the name string that has the following format:

namespace name

In the type name format, the namespace part followed by a space is only present for global type names. For global types and elements defined in schemas without a target namespace, the namespace part is empty but the space is still there. In the type name format, after the initial name component, up to three additional name components can be present, separated by commas. For example:

http://example.com/hello type

foo

foo,iterator

foo,const,iterator

The following set of predefined regular expressions is used to transform type names when the upper-camel-case naming convention is selected:

/(?:[^ ]* )?([^,]+)/\u$1/

/(?:[^ ]* )?([^,]+),([^,]+)/\u$1\u$2/

/(?:[^ ]* )?([^,]+),([^,]+),([^,]+)/\u$1\u$2\u$3/

/(?:[^ ]* )?([^,]+),([^,]+),([^,]+),([^,]+)/\u$1\u$2\u$3\u$4/

The accessor and modifier expressions (--*accessor-regex and --*modifier-regex) are evaluated on the name string that has the following format:

name[,name][,name]

After the initial name component, up to two additional name components can be present, separated by commas. For example:

foo

dom,document

foo,default,value

The following set of predefined regular expressions is used to transform accessor names when the java naming convention is selected:

/([^,]+)/get\u$1/

/([^,]+),([^,]+)/get\u$1\u$2/

/([^,]+),([^,]+),([^,]+)/get\u$1\u$2\u$3/

For the parser, serializer, and enumerator categories, the corresponding regular expressions are evaluated on local names of elements and on enumeration values, respectively. For example, the following predefined regular expression is used to transform parsing function names when the java naming convention is selected:

/(.+)/parse\u$1/

The const category is used to create C++ constant names for the element/wildcard/text content ids in ordered types. πŸŽ€

See also the REGEX AND SHELL QUOTING section below. πŸ‘€

✨ TYPE MAP ✨

Okay bestie, this one is a whole thing but it's SO worth it. Type map files are used in C++/Parser to define a mapping between XML Schema and C++ types. The compiler uses this information to determine the return types of post_* functions in parser skeletons corresponding to XML Schema types, plus the argument types for callbacks corresponding to elements and attributes of these types.

The compiler comes with a set of predefined mapping rules that map built-in XML Schema types to suitable C++ types (we're getting to those, don't worry) and map everything else to void. But if you provide your own type maps, you can override those predefined rules. Periodt. The format of the type map file is giving this:

namespace schema-namespace [ cxx-namespace ]
{
  ( include file-name; )*
  ([ type ] schema-type cxx-ret-type [ cxx-arg-type ]; )*
}

So here's the tea on each piece:

  • Both schema-namespace and schema-type are regex patterns, while cxx-namespace, cxx-ret-type, and cxx-arg-type are regex pattern substitutions. All names can be optionally enclosed in " " β€” for example, to include white-spaces. πŸ’…
  • schema-namespace determines the XML Schema namespace. The optional cxx-namespace is prefixed to every C++ type name in this namespace declaration.
  • cxx-ret-type is a C++ type name that gets used as a return type for the post_* functions.
  • The optional cxx-arg-type is an argument type for callback functions corresponding to elements and attributes of this type. If cxx-arg-type is not specified, it defaults to cxx-ret-type if cxx-ret-type ends with * or & (that is, it's a pointer or a reference) and const cxx-ret-type& otherwise.
  • file-name is a file name either in the " " or < > format and is added with the #include directive to the generated code.

The # character starts a comment that ends with a new line or end of file. To specify a name that contains #, enclose it in " ". Like, for example:

namespace http://www.example.com/xmlns/my my
{
  include "my.hxx";

  # Pass apples by value.
  #
  apple apple;

  # Pass oranges as pointers.
  #
  orange orange_t*;
}

In the example above, for the http://www.example.com/xmlns/my#orange XML Schema type, the my::orange_t* C++ type will be used as both return and argument types. Slay.

You can specify several namespace declarations in a single file. The namespace declaration can also be completely omitted, which maps types in a schema without a namespace. For instance:

include "my.hxx";
apple apple;

namespace http://www.example.com/xmlns/my
{
  orange "const orange_t*";
}

The compiler has a number of predefined mapping rules that can be presented as the following map files. The string-based XML Schema built-in types are mapped to either std::string or std::wstring depending on the character type selected with the --char-type option (char by default). 🫢

namespace http://www.w3.org/2001/XMLSchema
{
  boolean bool bool;

  byte "signed char" "signed char";
  unsignedByte "unsigned char" "unsigned char";

  short short short;
  unsignedShort "unsigned short" "unsigned short";

  int int int;
  unsignedInt "unsigned int" "unsigned int";

  long "long long" "long long";
  unsignedLong "unsigned long long" "unsigned long long";

  integer "long long" "long long";

  negativeInteger "long long" "long long";
  nonPositiveInteger "long long" "long long";

  positiveInteger "unsigned long long" "unsigned long long";
  nonNegativeInteger "unsigned long long" "unsigned long long";

  float float float;
  double double double;
  decimal double double;

  string std::string;
  normalizedString std::string;
  token std::string;
  Name std::string;
  NMTOKEN std::string;
  NCName std::string;
  ID std::string;
  IDREF std::string;
  language std::string;
  anyURI std::string;

  NMTOKENS xml_schema::string_sequence;
  IDREFS xml_schema::string_sequence;

  QName xml_schema::qname;

  base64Binary std::auto_ptr<xml_schema::buffer>
               std::auto_ptr<xml_schema::buffer>;
  hexBinary std::auto_ptr<xml_schema::buffer>
            std::auto_ptr<xml_schema::buffer>;

  date xml_schema::date;
  dateTime xml_schema::date_time;
  duration xml_schema::duration;
  gDay xml_schema::gday;
  gMonth xml_schema::gmonth;
  gMonthDay xml_schema::gmonth_day;
  gYear xml_schema::gyear;
  gYearMonth xml_schema::gyear_month;
  time xml_schema::time;
}

And the very last predefined rule maps anything that wasn't mapped by the previous rules to void:

namespace .*
{
  .* void void;
}

When you provide your own type maps with the --type-map option, they are evaluated first. That's the whole point, bestie β€” it lets you selectively override the predefined rules. πŸŽ€


🌈 REGEX AND SHELL QUOTING 🌈

When you're entering a regular expression argument in the shell command line, it's often necessary to use quoting (enclosing the argument in " " or ' ') so the shell doesn't interpret certain characters β€” like, spaces as argument separators and $ as variable expansions.

Unfortunately it's hard to achieve this in a manner that's portable across POSIX shells, such as those found on GNU/Linux and UNIX, and Windows shell. For example, if you use " " for quoting you'll get a wrong result with POSIX shells if your expression contains $. The standard way of dealing with this on POSIX systems is to use ' ' instead. Unfortunately, Windows shell does not remove ' ' from arguments when they are passed to applications. As a result you may have to use ' ' for POSIX and " " for Windows ($ is not treated as a special character on Windows). 😭

Alternatively, you can save regular expression options into a file, one option per line, and use this file with the --options-file option. With this approach you don't need to worry about shell quoting. Iconic problem-solving behaviour, honestly. ✨


🩺 DIAGNOSTICS 🩺

If the input file is not a valid W3C XML Schema definition, xsdcxx will issue diagnostic messages to STDERR and exit with non-zero exit code. It's giving "we're telling you what's wrong and we are NOT being subtle about it."


πŸ’€ BUGS πŸ’€

Send bug reports to the xsd-users@codesynthesis.com mailing list.


Copyright (c) 2005-2017 Code Synthesis Tools CC.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, version 1.2; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. Copy of the license can be obtained from http://codesynthesis.com/licenses/fdl-1.2.txt


Okay that's the whole page, babe. This one's XSDCXX version 4.1.0, dated July 2014, and it's XSDCXX(1) β€” manual page complete, no notes left behind, we ate and left zero crumbs. πŸ’…πŸŒΈ Go write some schemas, bestie. πŸ¦‹πŸ’–

πŸ“¦ where this page comes from