Namespace → Kotlin Package Mapping¶
Schema namespaces are URIs — an XSD targetNamespace or a JSON Schema $id. When you
don't supply an explicit package name, NamespacePackageMapper
(ca.esmcelroy.schema2class.core.naming) derives one. The convention follows JAXB,
adapted for Kotlin.
Default derivation¶
| Namespace | Package |
|---|---|
http://maven.apache.org/POM/4.0.0 |
org.apache.maven.pom._4_0_0 |
https://www.example.com:8443/schemas/order |
com.example.schemas.order |
http://example.com/schemas/common.xsd |
com.example.schemas.common |
urn:un:unece:uncefact:codelist:standard:UNECE:ActionCode:D24A |
un.unece.uncefact.codelist.standard.unece.actioncode.d24a |
| (no targetNamespace) | generated |
Rules:
http(s)://URIs — host labels reversed (a leadingwww.and any port are dropped), then path segments appended in order.urn:URIs — colon-separated segments in order; no reversal.- Segment sanitization — lowercase; characters outside
[a-z0-9]become_; segments starting with a digit get a_prefix; Kotlin hard keywords (fun,object, …) get a_suffix; a trailing.xsd/.json/.wsdlextension on the last segment is stripped.
Configuration¶
val mapper = NamespacePackageMapper(
// Prepended to every derived package (not to overrides).
basePackage = "com.corp.generated",
// Exact-match URI → package; used verbatim. Wins over derivation.
overrides = mapOf(
"urn:corp:billing:v2" to "com.corp.contracts.billing",
),
// Used when the schema has no namespace (default: "generated").
defaultPackage = "com.corp.generated.misc",
)
val model = XsdParser().parse(File("billing.xsd"), mapper)
Collisions¶
Two distinct namespaces can derive the same package (urn:test:a-b and urn:test:a_b
both sanitize to test.a_b). For multi-schema runs, use toPackages(namespaces),
which guarantees uniqueness by suffixing later entries in iteration order:
test.a_b, test.a_b_2, test.a_b_3, … Iteration order is the caller's input order,
so results are deterministic for a given schema set.
The multi-file XSD import resolver (schema2class-y7w) and the Gradle plugin use
toPackages so every imported namespace lands in a stable, distinct package.
Wire namespace overrides¶
Package derivation and XML wire namespaces are independent. For XSD models,
SchemaModel.namespace remains the schema namespace used for grouping and package
mapping, while SchemaModel.wireNamespace is what xmlutil annotations emit.
This matters for schemas with no targetNamespace, or contracts whose generated
package should not mirror the XML namespace required on the wire.
CLI:
schema2class generate \
--input envelope.xsd=com.corp.envelope \
--annotation-mode xmlutil \
--wire-namespace urn:wire:envelope
Gradle:
schema2class {
schemas {
create("envelope") {
source = file("schemas/envelope.xsd")
packageName = "com.corp.envelope"
annotationMode = "XMLUTIL"
wireNamespace = "urn:wire:envelope"
}
}
}
For multi-namespace XSD graphs, use namespace-specific overrides:
wireNamespaceOverrides.put("urn:schema:money", "urn:wire:money")