XStream双下划线问题解决与CDATA标记同时的方案 您所在的位置:网站首页 下划线的标记是什么 XStream双下划线问题解决与CDATA标记同时的方案

XStream双下划线问题解决与CDATA标记同时的方案

2024-07-01 10:26| 来源: 网络整理| 查看: 265

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为:

123456 hehedesk hehedesk 5654675 0000000000000000 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(""); } else { writer.write(text); } } }; } });

输出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:

123456 123456 hehedesk hehedesk 5654675 0000000000000000

注意:这里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 = 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来进行编译,而是直接返回节点名称。

@Override public 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(""); } else { writer.write(text); } } }; } });

输出XML:



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有