Search code examples
javaxmljaxb

JAXB: Add namespace to second level


I want to add the namespace urn:com.workday/bsvc to the second element in the xml i generate. This is what i want to generate:

enter image description here

But i don't know how to specify it in my class. I added this to my class Put_Absence_Input_Request : enter image description here


Solution

  • This download (zip) contains a stand-alone Maven project to unmarshal the given XML workday-01.xml file into JAXB objects and then marshal the objects back into XML, like this:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <root xmlns:wd="urn:com.workday/bsvo">
        <wd:Put_Absence_Input_Request wd:version="v39.2">
            <wd:Absence_Input_Data>
                <wd:Batch_ID>Import 15022023</wd:Batch_ID>
                <wd:Worker_Reference>
                    <wd:ID wd:type="Employee_ID">1741538</wd:ID>
                </wd:Worker_Reference>
                <wd:Absence_Component_Reference>
                    <wd:ID wd:type="Accrual_Code">FRA_Shadow_Accrual_for_Time_Offs_Impacting_Accrual_of_Paid_Annual_Leave_CP</wd:ID>
                </wd:Absence_Component_Reference>
                <wd:Start_Date>2023-01-01</wd:Start_Date>
                <wd:End_Date>2023-01-31</wd:End_Date>
                <wd:Reference_Date>2023-01-15</wd:Reference_Date>
                <wd:Hours>2.08</wd:Hours>
                <wd:Adjustment>false</wd:Adjustment>
            </wd:Absence_Input_Data>
        </wd:Put_Absence_Input_Request>
    </root>
    
    

    The root element does not declare a namespace for itself but it does declare a namespace for the child elements.

    Here's How

    The configuration of the "urn:com.workday/bsvo" namespace is declared in the JAXB context using:

    com/workday/bsvo/package-info.java

    @jakarta.xml.bind.annotation.XmlSchema
    (
        namespace = "urn:com.workday/bsvo",
        elementFormDefault = jakarta.xml.bind.annotation.XmlNsForm.QUALIFIED,
        xmlns =
        {
            @jakarta.xml.bind.annotation.XmlNs
            (
                prefix = "wd",
                namespaceURI = "urn:com.workday/bsvo"
            )
        }
    )
    package com.workday.bsvo;
    

    Additionally, the namespace prefix is optionally configured to be wd: to override the generic ns1 prefix.

    The Maven project generates the Java (JAXB) classes from these XML schemas and a binding file:

    The HiSrc HigherJAXB Maven Plugin is used to generate the JAXB classes:

    Note: This is a "schema first" design pattern; but, you can use the generated Java classes as a model for a "code first" approach.

    target
    └── generated-sources
        └── xjc
            ├── com
            │   └── workday
            │       ├── bsvo
            │       │   ├── AbsenceComponentReference.java
            │       │   ├── AbsenceInputData.java
            │       │   ├── ID.java
            │       │   ├── ObjectFactory.java
            │       │   ├── package-info.java
            │       │   ├── PutAbsenceInputRequest.java
            │       │   └── WorkerReference.java
            │       ├── ObjectFactory.java
            │       ├── package-info.java
            │       └── Root.java
            ├── JAXBDebug.java
            └── META-INF
                └── sun-jaxb.episode
    

    The root.xjb binding file customizes the Java package path for the namespace-less root classes and a child path for the workday classes to keep things orderly. The wd.xsd declares its own target namespace and the root.xsd intentionally omits a target namespace.

    Also, the root.xjb binding file customizes the workday level package-info.java to use the more friendly prefix, wd:. The HiSrc HyperJAXB Annox XJC Plugin is used to customize the prefix. This is optional. If this customization is omitted, JAXB will declare the "urn:com.workday/bsvo" namespace in package-info.java, as desired, but the prefix will be arbitrary (i.e. ns1).

    Also, the HiSrc BasicJAXB XJC Plugin is used to generate value specific methods for hashCode, equals and toString. The generation of these methods is optional but it provides a human-readable toString output for the sample Main.java application.

    Execution

    This is a stand-alone Maven project. After unzipping it to your local folder, you can run the test using:

    mvn -Ptest clean test
    

    Or execute the sample application using:

    mvn -Pexec clean compile exec:java
    

    This output shows the test results.

    Disclaimer: I am the maintainer for the HiSrc projects.