CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-jakarta-xml-bind--jakarta-xml-bind-api

Jakarta XML Binding API that automates the mapping between XML documents and Java objects through data binding

Pending
Overview
Eval results
Files

data-type-conversion.mddocs/

Data Type Conversion

Jakarta XML Binding provides comprehensive static utility methods for converting between Java types and XML Schema data types. The DatatypeConverter class handles all standard XML Schema primitive and derived types with robust parsing and formatting capabilities.

Capabilities

DatatypeConverter Static Methods

The DatatypeConverter class provides static methods for all XML Schema data types, supporting both parsing (String to Java) and printing (Java to String) operations.

public final class DatatypeConverter {
    // String type conversion
    public static String parseString(String lexicalXSDString);
    public static String printString(String val);
    
    // Integer type conversions
    public static java.math.BigInteger parseInteger(String lexicalXSDInteger);
    public static String printInteger(java.math.BigInteger val);
    
    public static int parseInt(String lexicalXSDInt);
    public static String printInt(int val);
    
    public static long parseLong(String lexicalXSDLong);
    public static String printLong(long val);
    
    public static short parseShort(String lexicalXSDShort);
    public static String printShort(short val);
    
    public static byte parseByte(String lexicalXSDByte);
    public static String printByte(byte val);
    
    // Unsigned integer conversions
    public static long parseUnsignedInt(String lexicalXSDUnsignedInt);
    public static String printUnsignedInt(long val);
    
    public static int parseUnsignedShort(String lexicalXSDUnsignedShort);
    public static String printUnsignedShort(int val);
    
    // Decimal type conversions
    public static java.math.BigDecimal parseDecimal(String lexicalXSDDecimal);
    public static String printDecimal(java.math.BigDecimal val);
    
    public static float parseFloat(String lexicalXSDFloat);
    public static String printFloat(float val);
    
    public static double parseDouble(String lexicalXSDDouble);
    public static String printDouble(double val);
    
    // Boolean conversion
    public static boolean parseBoolean(String lexicalXSDBoolean);
    public static String printBoolean(boolean val);
    
    // Date and time conversions
    public static java.util.Calendar parseDateTime(String lexicalXSDDateTime);
    public static String printDateTime(java.util.Calendar val);
    
    public static java.util.Calendar parseTime(String lexicalXSDTime);
    public static String printTime(java.util.Calendar val);
    
    public static java.util.Calendar parseDate(String lexicalXSDDate);
    public static String printDate(java.util.Calendar val);
    
    // Binary data conversions
    public static byte[] parseBase64Binary(String lexicalXSDBase64Binary);
    public static String printBase64Binary(byte[] val);
    
    public static byte[] parseHexBinary(String lexicalXSDHexBinary);
    public static String printHexBinary(byte[] val);
    
    // QName conversion
    public static javax.xml.namespace.QName parseQName(String lexicalXSDQName, javax.xml.namespace.NamespaceContext nsc);
    public static String printQName(javax.xml.namespace.QName val, javax.xml.namespace.NamespaceContext nsc);
    
    // Generic any simple type
    public static String parseAnySimpleType(String lexicalXSDAnySimpleType);
    public static String printAnySimpleType(String val);
    
    // Converter management
    public static void setDatatypeConverter(DatatypeConverterInterface converter);
}

Basic Type Conversions

Simple conversions for XML Schema primitive types.

Usage Examples:

// String conversions (identity operations with validation)
String xmlString = DatatypeConverter.printString("Hello World");
String javaString = DatatypeConverter.parseString(xmlString);

// Integer conversions
String xmlInt = DatatypeConverter.printInt(42);
int javaInt = DatatypeConverter.parseInt("42");

String xmlLong = DatatypeConverter.printLong(123456789L);
long javaLong = DatatypeConverter.parseLong("123456789");

BigInteger bigInt = DatatypeConverter.parseInteger("99999999999999999999");
String xmlBigInt = DatatypeConverter.printInteger(bigInt);

// Decimal conversions
BigDecimal decimal = DatatypeConverter.parseDecimal("123.456");
String xmlDecimal = DatatypeConverter.printDecimal(new BigDecimal("123.456"));

double d = DatatypeConverter.parseDouble("3.14159");
String xmlDouble = DatatypeConverter.printDouble(3.14159);

// Boolean conversion
boolean bool = DatatypeConverter.parseBoolean("true");  // or "1"
String xmlBool = DatatypeConverter.printBoolean(true);  // "true"

// Handles XML Schema boolean values: true, false, 1, 0
boolean xmlTrue = DatatypeConverter.parseBoolean("1");   // true
boolean xmlFalse = DatatypeConverter.parseBoolean("0");  // false

Date and Time Conversions

XML Schema date/time types map to Java Calendar objects with proper timezone handling.

Usage Examples:

// DateTime conversion (ISO 8601 format)
String xmlDateTime = "2023-12-25T10:30:00Z";
Calendar dateTime = DatatypeConverter.parseDateTime(xmlDateTime);

Calendar now = Calendar.getInstance();
String xmlNow = DatatypeConverter.printDateTime(now);
// Output: "2023-12-25T10:30:00.000Z" (with timezone)

// Date conversion (date only)
String xmlDate = "2023-12-25";
Calendar date = DatatypeConverter.parseDate(xmlDate);

Calendar today = Calendar.getInstance();
String xmlToday = DatatypeConverter.printDate(today);
// Output: "2023-12-25Z" (with timezone info)

// Time conversion (time only)
String xmlTime = "14:30:00";  
Calendar time = DatatypeConverter.parseTime(xmlTime);

Calendar currentTime = Calendar.getInstance();
String xmlCurrentTime = DatatypeConverter.printTime(currentTime);
// Output: "14:30:00.000Z" (with timezone)

// Working with timezones
String dateTimeWithTZ = "2023-12-25T10:30:00-05:00";
Calendar parsedWithTZ = DatatypeConverter.parseDateTime(dateTimeWithTZ);

// Get timezone information
TimeZone tz = parsedWithTZ.getTimeZone();
int offset = tz.getOffset(parsedWithTZ.getTimeInMillis());

Binary Data Conversions

XML Schema supports two binary data encoding formats: Base64 and hexadecimal.

Usage Examples:

// Base64 binary conversion
byte[] binaryData = "Hello World".getBytes("UTF-8");
String base64 = DatatypeConverter.printBase64Binary(binaryData);
// Output: "SGVsbG8gV29ybGQ="

byte[] decodedBase64 = DatatypeConverter.parseBase64Binary(base64);
String originalText = new String(decodedBase64, "UTF-8");

// Hexadecimal binary conversion  
String hex = DatatypeConverter.printHexBinary(binaryData);
// Output: "48656C6C6F20576F726C64"

byte[] decodedHex = DatatypeConverter.parseHexBinary(hex);

// Working with larger binary data
try (FileInputStream fis = new FileInputStream("document.pdf")) {
    byte[] fileBytes = fis.readAllBytes();
    String base64Document = DatatypeConverter.printBase64Binary(fileBytes);
    
    // Store base64Document in XML
    // Later retrieve and decode:
    byte[] restoredBytes = DatatypeConverter.parseBase64Binary(base64Document);
    
    try (FileOutputStream fos = new FileOutputStream("restored.pdf")) {
        fos.write(restoredBytes);
    }
}

QName Conversions

QName conversions require namespace context for proper prefix resolution.

Usage Examples:

// Create namespace context
NamespaceContext nsContext = new NamespaceContext() {
    @Override
    public String getNamespaceURI(String prefix) {
        switch (prefix) {
            case "hr": return "http://company.com/hr";
            case "common": return "http://company.com/common";
            case XMLConstants.XML_NS_PREFIX: return XMLConstants.XML_NS_URI;
            case XMLConstants.XMLNS_ATTRIBUTE: return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
            default: return XMLConstants.NULL_NS_URI;
        }
    }
    
    @Override
    public String getPrefix(String namespaceURI) {
        switch (namespaceURI) {
            case "http://company.com/hr": return "hr";
            case "http://company.com/common": return "common";
            default: return null;
        }
    }
    
    @Override
    public Iterator<String> getPrefixes(String namespaceURI) {
        return Collections.singletonList(getPrefix(namespaceURI)).iterator();
    }
};

// Parse QName from XML
String xmlQName = "hr:employee";
QName qname = DatatypeConverter.parseQName(xmlQName, nsContext);
// QName{http://company.com/hr}employee

// Print QName to XML
QName qnameToSerialize = new QName("http://company.com/hr", "employee");
String xmlOutput = DatatypeConverter.printQName(qnameToSerialize, nsContext);
// Output: "hr:employee"

// Handle unprefixed QNames (default namespace)
QName localName = new QName("employee");  // No namespace
String xmlLocal = DatatypeConverter.printQName(localName, nsContext);
// Output: "employee"

DatatypeConverterInterface

The interface that defines the contract for all datatype conversion operations.

public interface DatatypeConverterInterface {
    // String type conversion
    String parseString(String lexicalXSDString);
    String printString(String val);
    
    // Integer type conversions
    java.math.BigInteger parseInteger(String lexicalXSDInteger);
    String printInteger(java.math.BigInteger val);
    
    int parseInt(String lexicalXSDInt);
    String printInt(int val);
    
    long parseLong(String lexicalXSDLong);
    String printLong(long val);
    
    short parseShort(String lexicalXSDShort);
    String printShort(short val);
    
    byte parseByte(String lexicalXSDByte);
    String printByte(byte val);
    
    // Unsigned integer conversions
    long parseUnsignedInt(String lexicalXSDUnsignedInt);
    String printUnsignedInt(long val);
    
    int parseUnsignedShort(String lexicalXSDUnsignedShort);
    String printUnsignedShort(int val);
    
    // Decimal type conversions
    java.math.BigDecimal parseDecimal(String lexicalXSDDecimal);
    String printDecimal(java.math.BigDecimal val);
    
    float parseFloat(String lexicalXSDFloat);
    String printFloat(float val);
    
    double parseDouble(String lexicalXSDDouble);
    String printDouble(double val);
    
    // Boolean conversion
    boolean parseBoolean(String lexicalXSDBoolean);
    String printBoolean(boolean val);
    
    // Date and time conversions
    java.util.Calendar parseDateTime(String lexicalXSDDateTime);
    String printDateTime(java.util.Calendar val);
    
    java.util.Calendar parseTime(String lexicalXSDTime);
    String printTime(java.util.Calendar val);
    
    java.util.Calendar parseDate(String lexicalXSDDate);
    String printDate(java.util.Calendar val);
    
    // Binary data conversions
    byte[] parseBase64Binary(String lexicalXSDBase64Binary);
    String printBase64Binary(byte[] val);
    
    byte[] parseHexBinary(String lexicalXSDHexBinary);
    String printHexBinary(byte[] val);
    
    // QName conversion
    javax.xml.namespace.QName parseQName(String lexicalXSDQName, javax.xml.namespace.NamespaceContext nsc);
    String printQName(javax.xml.namespace.QName val, javax.xml.namespace.NamespaceContext nsc);
    
    // Generic any simple type
    String parseAnySimpleType(String lexicalXSDAnySimpleType);
    String printAnySimpleType(String val);
}

Custom Converter Implementation

You can provide custom implementations of the DatatypeConverterInterface for specialized processing.

Usage Example:

// Custom converter with enhanced date handling
public class CustomDatatypeConverter implements DatatypeConverterInterface {
    private static final DateTimeFormatter CUSTOM_DATE_FORMAT = 
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    @Override
    public Calendar parseDateTime(String lexicalXSDDateTime) {
        try {
            // Try standard XML Schema format first
            return javax.xml.bind.DatatypeConverter.parseDateTime(lexicalXSDDateTime);
        } catch (Exception e) {
            // Fall back to custom format
            LocalDateTime ldt = LocalDateTime.parse(lexicalXSDDateTime, CUSTOM_DATE_FORMAT);
            Calendar cal = Calendar.getInstance();
            cal.setTime(Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant()));
            return cal;
        }
    }
    
    @Override
    public String printDateTime(Calendar val) {
        // Use standard XML Schema format for output
        return javax.xml.bind.DatatypeConverter.printDateTime(val);
    }
    
    // Implement other methods by delegating to default implementation
    @Override
    public String parseString(String lexicalXSDString) {
        return javax.xml.bind.DatatypeConverter.parseString(lexicalXSDString);
    }
    
    // ... implement remaining methods
}

// Set custom converter
DatatypeConverter.setDatatypeConverter(new CustomDatatypeConverter());

// Now all JAXB operations will use the custom converter

Error Handling and Edge Cases

Common Parsing Errors

// Handle parsing errors gracefully
public class SafeDataTypeUtils {
    
    public static Integer parseIntSafely(String value) {
        try {
            return DatatypeConverter.parseInt(value);
        } catch (NumberFormatException e) {
            System.err.println("Invalid integer format: " + value);
            return null;
        }
    }
    
    public static Calendar parseDateTimeSafely(String value) {
        try {
            return DatatypeConverter.parseDateTime(value);
        } catch (IllegalArgumentException e) {
            System.err.println("Invalid datetime format: " + value);
            return null;
        }
    }
    
    public static byte[] parseBase64Safely(String value) {
        try {
            return DatatypeConverter.parseBase64Binary(value);
        } catch (IllegalArgumentException e) {
            System.err.println("Invalid base64 format: " + value);
            return null;
        }
    }
}

Null and Empty Value Handling

// Safe handling of null and empty values
public class NullSafeConverter {
    
    public static String printStringSafe(String value) {
        return value != null ? DatatypeConverter.printString(value) : null;
    }
    
    public static String parseStringSafe(String xmlValue) {
        return xmlValue != null && !xmlValue.isEmpty() 
            ? DatatypeConverter.parseString(xmlValue) 
            : null;
    }
    
    public static String printCalendarSafe(Calendar value) {
        return value != null ? DatatypeConverter.printDateTime(value) : null;
    }
    
    public static String printBinarySafe(byte[] value) {
        return value != null && value.length > 0 
            ? DatatypeConverter.printBase64Binary(value) 
            : null;
    }
}

Validation and Format Checking

// Validation utilities for XML Schema types
public class XSDTypeValidator {
    
    private static final Pattern XSD_DATETIME_PATTERN = Pattern.compile(
        "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})?"
    );
    
    private static final Pattern XSD_DATE_PATTERN = Pattern.compile(
        "\\d{4}-\\d{2}-\\d{2}(Z|[+-]\\d{2}:\\d{2})?"
    );
    
    public static boolean isValidDateTime(String value) {
        if (value == null || value.isEmpty()) return false;
        
        try {
            DatatypeConverter.parseDateTime(value);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    public static boolean isValidBase64(String value) {
        if (value == null || value.isEmpty()) return false;
        
        try {
            DatatypeConverter.parseBase64Binary(value);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    public static boolean isValidInteger(String value) {
        if (value == null || value.isEmpty()) return false;
        
        try {
            DatatypeConverter.parseInteger(value);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

Integration with JAXB Processing

The DatatypeConverter is automatically used by JAXB during marshalling and unmarshalling operations:

// JAXB automatically uses DatatypeConverter for built-in types
@XmlRootElement
public class Document {
    @XmlElement
    private Calendar createdDate;      // Uses parseDateTime/printDateTime
    
    @XmlElement  
    private BigDecimal amount;         // Uses parseDecimal/printDecimal
    
    @XmlElement
    private byte[] signature;          // Uses parseBase64Binary/printBase64Binary
    
    @XmlAttribute
    private boolean active;           // Uses parseBoolean/printBoolean
}

// Custom converter affects all JAXB operations
DatatypeConverter.setDatatypeConverter(new CustomDatatypeConverter());

JAXBContext context = JAXBContext.newInstance(Document.class);
// All marshalling/unmarshalling now uses custom converter

Install with Tessl CLI

npx tessl i tessl/maven-jakarta-xml-bind--jakarta-xml-bind-api

docs

binary-attachments.md

convenience-api.md

core-binding.md

data-type-conversion.md

index.md

transform-integration.md

type-adapters.md

validation-error-handling.md

xml-mapping-annotations.md

tile.json