Search code examples
javajaxbtagsschemamarshalling

How can I get JAXB to generate empty tags for elements with restrictions?


I've been reading up how to get JAXB to generate empty element tags when marshalling (i.e. <name/>) and it seems as if I need to specify an empty string "". My schema has restrictions on some elements that require at least 1 character if the element is specified.

How can I get JAXB to generate the empty element tags without throwing validation errors on the restrictions?

EDIT:

Updated information - I have an element name that is referenced as part of a sequence in my XSD. This element is required in the sequence as it does not have an atrribute of minOccurs="0". Unfortunately I have no control to change the XSD, so I cannot add the attribute.

When I enter an empty string "" so that jaxb creates the empty element, I get a validation error because the name element has a restriction of <xs:minLength value="1"/> I want to be able to validate the XML to check for other issues, but skip this particular validation.


Solution

  • Figured out how to work around and ignore specific validations. I created an an event handler that implemented ValdationEventHandler for my JAXB code that looks like this:

    public class MyEventHandler implements ValidationEventHandler {
    
    private static final Logger logger = Logger.getLogger(MyEventHandler.class);
    
    @Override
    public boolean handleEvent(ValidationEvent event) {
    
        if(event.getLocator().getObject() instanceof com.path.MyObject || 
                event.getMessage().contains("length = '0' is not facet-valid with respect to minLength '1' for type '#AnonType_name'")){
            return true;
        }
        logger.info("\nEVENT");
        logger.info("SEVERITY: " + event.getSeverity());
        logger.info("MESSAGE: " + event.getMessage());
        logger.info("LINKED EXCEPTION: " + event.getLinkedException());
        logger.info("LOCATOR");
        logger.info(" LINE NUMBER: " + event.getLocator().getLineNumber());
        logger.info(" COLUMN NUMBER: " + event.getLocator().getColumnNumber());
        logger.info(" OFFSET: " + event.getLocator().getOffset());
        logger.info(" OBJECT: " + event.getLocator().getObject());
        logger.info(" NODE: " + event.getLocator().getNode());
        logger.info(" URL: " + event.getLocator().getURL());
        return false;
    }
    

    In the class with the JAXB Marshaller I added the event handler like this:

    jaxbMarshaller.setEventHandler(new MyEventHandler());
    

    When there is a validation event, it goes into the event handler, checks if it's the correct object and correct error on that object, if so it returns true which tells the marshaller to continue. If it's not this error, it will print out all the information about the event and return false so the marshalling fails.