dalvarezmartinez1
dalvarezmartinez1

Reputation: 1405

JAXB remove trailing spaces, or prompt of invalid document

So I have some JAXB annotated class, and an xml representing this class. When I unmarshal the xml doc to the class, all works fine, the problem is, I have some empty spaces, and I want JAXB to either remove them, or prompt me, that the document is wrong, according to the schema I set in the unmarshaller, so far I tried:

  1. Create a custom type with the restriction: "xs:pattern value="\S.+\S"
  2. Use "xs:normalizedString" as the type
  3. Use "xs:whiteSpace value="collapse" " in a custom type

None of the above works. Any idea why? Is this expected behavior?

Note: I don't want to use @XmlJavaTypeAdapter(MyAwesomeAdapter.class).

EDIT:

I realize that the original question was about unmarshalling, and the code below is about marshalling, but they are complementary processes, pretty similar.

The class:

@XmlRootElement(name = "person")
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

@XmlElement
private String name;

public Person() {

}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

private static final class MyValidationEventHandler implements ValidationEventHandler {

    @Override
    public boolean handleEvent(ValidationEvent event) {
        System.out.println(event.getMessage());
        return true;
    }
}

public static void main(String[] args) throws JAXBException, SAXException {
    JAXBContext context = JAXBContext.newInstance(Person.class);
    Marshaller marshaller = context.createMarshaller();

    SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = sf.newSchema(new File("src/person.xsd"));
    marshaller.setSchema(schema);

    marshaller.setEventHandler(new MyValidationEventHandler());

    Person person = new Person();
    person.setName("Name ");
    marshaller.marshal(person, System.out);
}

}

The schema:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="person">
        <xs:complexType>
          <xs:sequence>
            <xs:element type="xs:normalizedString" name="name"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
</xs:schema>

Output:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><person><name>Name </name></person>

As you can see, there is no validation error, an the output contains a space.

EDIT AFTER ACCEPTING ANSWER It seems like the pattern works correctly.

    <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">   
    <xs:simpleType name="NameType">
        <xs:restriction base='xs:string'>
          <xs:pattern value='\S.*\S'/>
        </xs:restriction>
    </xs:simpleType>

    <xs:element name="person">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="name" type="NameType"/>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
</xs:schema>

Upvotes: 2

Views: 2887

Answers (2)

laune
laune

Reputation: 31290

This works for me, using jdk1.8.0_20.

For validation, you can use an XML Schema containing a facet:

<xs:element  name="name">
  <xs:simpleType>
    <xs:restriction base='xs:normalizedString'>
      <xs:pattern value='\S.*\S'/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

You can set the handler (as in your code) or catch the exception that will be thrown:

event: [severity=FATAL_ERROR,message=cvc-type.3.1.3: The value 'Name  ' of 
element 'name' is not valid.,locator=[url=null,line=-1,column=-1,node=null,
object=generated.Person@7cca494b,field=null]]

It works for both marshalling and unmarshalling.

Upvotes: 0

bdoughan
bdoughan

Reputation: 148977

Starting from XML Schema

The schema type should be set to xs:token. This will cause the corresponding property to be generated with XmlAdapter(CollapsedStringAdapter.class).

Starting from Java Classes

What I want is to use my own JAXB annotated classes, no need for JAXB to generate them for me.

You can leverage the existing CollapsedStringAdapter on your own property two have the whitespace stripped during the unmarshal.

@XmlAdapter(CollapsedStringAdapter.class)
public String getYourProperty() {
    return yourProperty;
}

I was hoping that the xsd schema that I set in the unmarshaller, would help JAXB trim, or enforce my normalizedString, or whiteSpace constraints.

I would expect a validation event to occur during the unmarshal if you specified a Schema on the Unmarshaller. Can you try registering a ValidationEventHandler on the Unmarshaller to see if anything is thrown? It may be occuring at a low enough severity that it doesn't stop the unmarshal.

Upvotes: 2

Related Questions