XStream双下划线问题解决与CDATA标记同时的方案
来源:互联网 发布:2017淘宝补单平台 编辑:程序博客网 时间:2024/05/17 06:13
1、问题
在微信开发过程中,需要进行xml格式的数据传输。有些微信接口的xml数据中需要加上CDATA标记,而大部分的xml数据的标签名都带有下划线。注意,微信接口中的数据是有下划线的,是“_”不是“-”,让我很郁闷。
2、使用XStream把Java对象转成xml格式的数据
UnifiedOrder unifiedOrder = new UnifiedOrder(); unifiedOrder.setAppid("123456"); unifiedOrder.setAttach("hehedesk"); unifiedOrder.setBody("hehedesk"); unifiedOrder.setOpenid("5654675"); unifiedOrder.setSign("0000000000000000"); XStream stream = new XStream(); stream.alias("xml", unifiedOrder.getClass()); String xml = stream.toXML(unifiedOrder); System.out.println(xml);
输出XML为:
<xml> <appid>123456</appid> <attach>hehedesk</attach> <body>hehedesk</body> <openid>5654675</openid> <sign>0000000000000000</sign></xml>
3、为数据加上CDATA标记
修改XStream的实现就可以。
XStream stream = new XStream(new XppDriver(new NoNameCoder()) { @Override public HierarchicalStreamWriter createWriter(Writer out) { return new PrettyPrintWriter(out) { // 对所有xml节点的转换都增加CDATA标记 boolean cdata = true; @Override @SuppressWarnings("rawtypes") public void startNode(String name, Class clazz) { super.startNode(name, clazz); } @Override protected void writeText(QuickWriter writer, String text) { if (cdata) { writer.write("<![CDATA["); writer.write(text); writer.write("]]>"); } else { writer.write(text); } } }; } });
输出XML为:
<xml> <appid><![CDATA[123456]]></appid> <attach><![CDATA[hehedesk]]></attach> <body><![CDATA[hehedesk]]></body> <openid><![CDATA[5654675]]></openid> <sign><![CDATA[0000000000000000]]></sign></xml>
4、当对象属性带下划线时,XStream转换成双下划线
UnifiedOrder unifiedOrder = new UnifiedOrder(); unifiedOrder.setAppid("123456"); unifiedOrder.setAttach("hehedesk"); unifiedOrder.setBody("hehedesk"); unifiedOrder.setOpenid("5654675"); unifiedOrder.setSign("0000000000000000"); unifiedOrder.setMch_id("123456"); XStream stream = new XStream(); stream.alias("xml", unifiedOrder.getClass()); String xml = stream.toXML(unifiedOrder);
输出XML:
<xml> <appid>123456</appid> <mch__id>123456</mch__id> <attach>hehedesk</attach> <body>hehedesk</body> <openid>5654675</openid> <sign>0000000000000000</sign></xml>
注意:这里mch_id的下线线由XStream转成了”__”。
度娘上找到的解决方法:
new DomDriver(null,new XmlFriendlyNameCoder("_-", "_"))
经过测试,XmlFriendlyNameCoder与XppDriver不能同时存在。so,问题来了。如何才能让两者共存呢。
5、双下划线问题解决与CDATA标记同时的方案
双下划线问题的产生是因为XStream默认的转换方式中定义了对特殊字符的转换,代码如下:
//XmlFriendlyNameCoder.encodeName(String name)for (; i < length; i++ ) { char c = name.charAt(i); if (c == '$' || c == '_' || c <= 27 || c >= 127) { break; } }
也就是说,我们在转换的过程中,不对特殊字符进行转换就可以了。
XppDriver类中有对字符转换的方法:
/** * Encode the node name into the name of the target format. * * @param name the original name * @return the name in the target format * @since 1.4 */ public String encodeNode(String name) { return nameCoder.encodeNode(name); }
这里可以看到,XppDriver的encodeNode是把节点的名称进行格式化。然后调用nameCoder对象对名字进行编译。
我们在XppDriver的子类中,重写此方法,不再像XppDriver那样调用nameCoder来进行编译,而是直接返回节点名称。
@Overridepublic String encodeNode(String name) { return name;}
完整代码如下:
XStream stream = new XStream(new XppDriver(new NoNameCoder()) { @Override public HierarchicalStreamWriter createWriter(Writer out) { return new PrettyPrintWriter(out) { // 对所有xml节点的转换都增加CDATA标记 boolean cdata = true; @Override @SuppressWarnings("rawtypes") public void startNode(String name, Class clazz) { super.startNode(name, clazz); } @Override public String encodeNode(String name) { return name; } @Override protected void writeText(QuickWriter writer, String text) { if (cdata) { writer.write("<![CDATA["); writer.write(text); writer.write("]]>"); } else { writer.write(text); } } }; } });
输出XML:
<xml> <appid><![CDATA[123456]]></appid> <mch_id><![CDATA[1111111]]></mch_id> <attach><![CDATA[hehedesk]]></attach> <body><![CDATA[hehedesk]]></body> <openid><![CDATA[5654675]]></openid> <trade_type><![CDATA[JSAPI]]></trade_type> <sign><![CDATA[0000000000000000]]></sign> <device_info><![CDATA[WEB]]></device_info></xml>
2 0
- XStream双下划线问题解决与CDATA标记同时的方案
- CDATA标记的作用
- CDATA标记的作用
- XStream对所有xml节点转换时增加CDATA标记
- XStream支持CDATA标签
- XStream支持CDATA标签
- XStream支持CDATA标签
- XStream支持CDATA标签
- 使用XStream进行XML与对象的互相转换 下划线问题
- VIM高亮显示当前行只显示下划线的问题解决方案
- XStream 下划线 bug
- python 里面的单下划线与双下划线的区别
- python 里面的单下划线与双下划线的区别
- python 里面的单下划线与双下划线的区别
- XML-CDATA标记
- XML中的CDATA标记
- Python-单下划线与双下划线的区别
- python 单下划线与双下划线定义变量的区别
- 使用ReactiveCocoa实现iOS平台响应式编程
- servletContextListener监听器调用问题
- 加载大图片时,出现的OOM异常,以及处理OOM异常的方法
- android open gl es2.0 学习
- iOS笔记之tableView
- XStream双下划线问题解决与CDATA标记同时的方案
- ScheduledExecutorService
- 图案打印
- 原来现在常见的显示器不是真 8 位的,而是 6 位的……
- R语言-格式化输出
- [原]支付宝无线支付服务端接入C++
- Android快速SDK(13)拍照裁剪库PhotoGraph【傻瓜模式】
- java向ORACLE插入时间
- 红包算法