【发布时间】:2018-10-18 16:48:10
【问题描述】:
我们正在使用 JAXB 来解组我们无法更改的预存储 XML。不幸的是,预存的 XML 包含一些 HTML 括号,< and >, without CDATA.。例如,我们必须用 JAXB 解组(注意没有 CDATA):
<Article>
<ArticleTitle>Note the unescaped inner HTML (T<sub>3</sub>) in the title</ArticleTitle>
<Abstract>
<AbstractText>This is another element that has unescaped HTML: T<sub>3</sub>. </AbstractText>
</Abstract>
</Article>
我们需要保留上面的 HTML 数据。 JAXB 对此感到窒息,并为我们提供了不正确的模型值。
一种可行的解决方案是使用@XmlAnyElement,然后实现DomHandler(见下文)。
但不幸的是,每个类只允许使用 1 个 @XmlAnyElement。如果我为标题和摘要添加多个,则每次只有一个有效。因此此解决方案仅适用于有此问题的 1 个字段。我试过实现XmlAdapter(不是DomHandler),但字符串已经被截断,所以我不能使用那个解决方案,只有这个。
Force jaxb unmarshaller to ignore html Tags
@XmlAnyElement(value=AbstractTextHandler.class)
protected String abstractText=null;
然后实施
public class AbstractTextHandler implements DomHandler<String, StreamResult> {
private final Logger log = Logger.getLogger(getClass().getName());
private static final String START_TAG = "<Abstract>";
private static final String END_TAG = "</Abstract>";
private StringWriter xmlWriter = new StringWriter();
public StreamResult createUnmarshaller(ValidationEventHandler errorHandler) {
return new StreamResult(xmlWriter);
}
public String getElement(StreamResult rt) {
String xml = rt.getWriter().toString();
int beginIndex = xml.indexOf(START_TAG) + START_TAG.length();
int endIndex = xml.indexOf(END_TAG);
String result = xml.substring(beginIndex, endIndex);
log.info("Processing.." + result);
return result;
}
public Source marshal(String n, ValidationEventHandler errorHandler) {
try {
String xml = START_TAG + n.trim() + END_TAG;
StringReader xmlReader = new StringReader(xml);
return new StreamSource(xmlReader);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
}
这需要适用于多个字段,但只允许使用 1 个@XmlAnyElement。
我们有没有办法使用 SAX 解析器或其他东西来处理我们自己的 XML 编组,以避免在这些 HTML 括号上窒息?还是有@XmlAnyElement 的解决方法?
【问题讨论】: