Force jaxb unmarshaller to ignore html Tags

2019-06-13 17:42发布

I am using JAXB to convert string xml data to POJO as follows.

JAXBContext jaxbContext = JAXBContext.newInstance(Employee.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(temp);
Employee emp = (Employee) unmarshaller.unmarshal(reader); 

It goes fine, but it's always trying to validate text of each element during unmarshal and sometimes got failed. That I don't want, because in text there are lot of html tags and sometimes they are erroneous too.

So, I want JAXB to skip the entire text and pass it as it is to form POJO data. Is there any way to achieve this. Any help will be appreciated.

1条回答
我想做一个坏孩纸
2楼-- · 2019-06-13 18:22

Here is an example, you need to use @XmlAnyElement to get the content as it is without using CDATA.

Employee.java:

import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Employee {
private long id;
private String name;
private int age;
public long getId() {
    return id;
}
@XmlAttribute
public void setId(long id) {
    this.id = id;
}
@Override
public String toString() {
    return "Employee [id=" + id + ", name=" + name + ", age=" + age + "]";
}
public String getName() {
    return name;
}
@XmlAnyElement(NameHandler.class)
public void setName(String name) {
    this.name = name;
}
public int getAge() {
    return age;
}
@XmlElement
public void setAge(int age) {
    this.age = age;
}
}

NameHandler.java:

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.annotation.DomHandler;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class NameHandler implements DomHandler<String, StreamResult> {

      private static final String NAME_START_TAG = "<name>";
        private static final String NAME_END_TAG = "</name>";

        private StringWriter xmlWriter = new StringWriter();
    @Override
    public StreamResult createUnmarshaller(ValidationEventHandler errorHandler) {
        return new StreamResult(xmlWriter);
    }

    @Override
    public String getElement(StreamResult rt) {
         String xml = rt.getWriter().toString();
            int beginIndex = xml.indexOf(NAME_START_TAG) + NAME_START_TAG.length();
            int endIndex = xml.indexOf(NAME_END_TAG);
            return xml.substring(beginIndex, endIndex);
    }

    @Override
    public Source marshal(String n, ValidationEventHandler errorHandler) {
         try {
                String xml = NAME_START_TAG + n.trim() + NAME_END_TAG;
                StringReader xmlReader = new StringReader(xml);
                return new StreamSource(xmlReader);
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
    }

}

JAXB:

import java.io.StringReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

public class JAXBExample {
    public static void main(String[] args) {

     try {
 String temp ="<employee id=\"1001\"><age>25</age><name>myemp<p>content inside tags</p></name></employee>";
        JAXBContext jaxbContext = JAXBContext.newInstance(Employee.class);
 StringReader reader = new StringReader(temp);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        Employee emp = (Employee) jaxbUnmarshaller.unmarshal(reader);
        System.out.println(emp);

      } catch (JAXBException e) {
        e.printStackTrace();
      }

    }
}

prints the content as it is:

Employee [id=1001, name=myemp<p>content inside tags</p>, age=25]

Hope it helps.

查看更多
登录 后发表回答