如何为含&字符的XML字符串创建XMLStreamReader且无需替换完成反序列化
未转义&字符XML反序列化无需全局替换的解决方案
你当前遇到的核心问题是原始XML中存在未转义的&字符,不符合XML语法规范,默认XML解析器会直接抛出解析错误。无需调用replace/replaceAll全局替换字符串的可行方案如下:
方案1:使用支持宽松解析模式的StAX实现(推荐)
使用Woodstox这类第三方StAX解析实现,通过开启内置的宽松容错模式,自动处理未转义&等非规范XML问题,无需修改原始字符串也不需要自定义解析逻辑:
// 引入Woodstox后使用WstxInputFactory创建解析工厂 XMLInputFactory xif = new WstxInputFactory(); // 开启宽松容错模式,自动兼容未转义&、缺失属性引号等常见非规范问题 xif.setProperty(WstxInputProperties.P_IS_TOLERANT, Boolean.TRUE); // 后续逻辑和原有代码一致 String test = "<Res>Abc & Def</Res>"; StringReader sr = new StringReader(test); try { XMLStreamReader reader = xif.createXMLStreamReader(sr); JAXBContext jaxbContext = JAXBContext.newInstance(BluelineReprintInvoiceResponseData.class); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); Object o = unmarshaller.unmarshal(reader); } catch(Exception ex) { ex.printStackTrace(); }
方案2:使用DOM宽松解析模式
通过JDK内置的DOM解析器开启容错开关,忽略未转义字符的解析错误,先解析为DOM对象后再交给JAXB反序列化:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // 开启致命错误后继续解析的开关 dbf.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true); DocumentBuilder db = dbf.newDocumentBuilder(); // 自定义错误处理器,忽略未转义字符相关的解析错误 db.setErrorHandler(new ErrorHandler() { @Override public void warning(SAXParseException exception) throws SAXException {} @Override public void error(SAXParseException exception) throws SAXException {} @Override public void fatalError(SAXParseException exception) throws SAXException {} }); Document doc = db.parse(new InputSource(new StringReader(test))); // 直接用DOM对象执行反序列化 JAXBContext jaxbContext = JAXBContext.newInstance(BluelineReprintInvoiceResponseData.class); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); Object o = unmarshaller.unmarshal(doc);
方案3:自定义XMLStreamReader包装层
自定义XMLStreamReader的包装类,在流读取过程中实时处理未转义的&字符,不需要提前修改整个原始字符串,适合需要自定义特殊字符处理逻辑的场景。
注意:以上所有宽松解析方案均为XML规范外的兼容实现,仅适用于确认XML除未转义&外无其他严重格式错误的场景。生产环境优先建议推动XML生成方按规范转义&、<、>等XML特殊字符,从根源避免解析问题。
内容的提问来源于stack exchange,提问作者Aman Kumar
相关产品推荐
相关产品推荐

