XML组装解析的困扰小问题

1 问题表述

在开发一个java类与xml的组装代码中,之前因为不熟悉相关工具使用遇到三个小问题。

1.1其一:非-常规节点的叶子值显示

经过研究,我最终通过
@XmlJavaTypeAdapter(NullStringAdapter.class)
定义一个类似于NullStringAdapter.class的叶子节点,然后通过重写unmarshall和marshall方法可以得到自己想要的xml输出形式,举例如下:

package yang.toxml;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class NullStringAdapter extends XmlAdapter<String, Boolean> {
    @Override
    public Boolean unmarshal(String v) throws Exception {
        if("".equals(v)) {
            return true;
        }
        return false;
    }
    @Override
    public String marshal(Boolean v) throws Exception {
        if(v) {
            return null;
        }
        return "";
    }
}

1.2 其二:特殊容器节点类型转换

问题二则比问题一更进一步,就是复杂结构的转换,一个复杂java结构,希望在xml显示的时候换一种形式和结构去呈现里面的内容,简单说明就是例如需要组装xml的类是class1,但是我希望以完全不同层次的class2去呈现class里面的值,有了问题1解决的铺垫,我首先想到的解决策略就是继续使用@XmlJavaTypeAdapter注解,去重写unmarshal和marshal方法,但是因为见到了太多以

public class NullStringAdapter extends XmlAdapter<String, Boolean>

我认为这个XmlAdapter的拓展解析方法,泛型的第一个入参只能是String,即:Adapter提供了一个xml字符串和java类转换的桥梁,这种错误认识,让我很快完成了代码,也实现了这种特殊class层次结构的xml产生,但是却发生了问题三:产生的xml中发生了一些奇怪的元素,本来是>或<号的确显示的是&lt ; 和&gt ; 所以打印看到的String xml显得奇奇怪怪的;

1.3 问题三:xml奇怪的打印&lt ; 和&gt ;

问题现象是控制台打印会看到许多本该是> <号地方也就是用XmlAdapter适配得到的下层节点,原因我查找许久没看出来,最终就放弃了这方法,转为用更严格的层次结构去约束java类,以得到预期的xml数据。

连续遇到三个问题,当我解决第一个时候充满了动力,找到了较好的方案,第二个时就有些松懈,忽略了一些更好的尝试,第三个遇到后再短暂的发现此路不通后,我就选择了绕行,错过了一次学习和发现的机会,在许多天过后的一次偶尔再现xml打印问题,让我对整个问题解决、程序员习惯培养、xml组装和解析技术细节,有了更深刻的认识;

2 分析错过的学习机会

2.1 XmlAdapter方法重写

public class NullStringAdapter extends XmlAdapter<String, Boolean>

所有jaxb类型的重新适配继承自XmlAdapter,它的定义如下:

public abstract class XmlAdapter<ValueType,BoundType> {

首先确定的是它泛型入参ValueType并不是一个定值,而我因为网上的代码和自己写了许多问题1叶子节点的转换,惯性思维把第一个参数只认为可以填写为String,这里就错过了一个更简单的值类型灵活适配,通过许久后再现问题,我完成了这样一个尝试,确认问题成功:

package yang.toxml;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class NullStringAdapter extends XmlAdapter<DataDing, Boolean> {
    @Override
    public Boolean unmarshal(DataDing v) throws Exception {
        if("".equals(v)) {
            return true;
        }
        return false;
    }
    @Override
    public DataDing marshal(Boolean v) throws Exception {
        DataDing ding = new DataDing("true","false");
        return ding;
    }
}

分析原因:
a-惯性思维,想当然理解一个类,没有充分去查看相关类说明,也没有动手去构建一个工程去做充分尝试;
b-测试及尝试不充分;

2.2 xml转义字符学习

如果第一次遇到转义特殊字符问题,我在网上积极去搜索一下&lt ; 和&gt ;这些打印的含义,耐心一点大概就能知道这些特殊字符在解析中的由来,< > &这几个字符在xml通常是有特殊含义的所以在显示中如果节点值要输入这样的字符值,必须要经过处理,虽然这些是浏览器解析器自动完成的,这里就得到了问题二和问题三解决的一个次优的方案,如果还是希望层次结构变化,实现class1层次映射成class2,作相关xml的显示,仍然在Adapter入参第一个参数中可以填入String,但是在marshall方法产生字符串结尾,必须要将所有转义字符进行一次字符串的排查过滤,“”.replace(“~~~”)方法就可以完成,这里不是最好的方案,但是仍然可以解决问题;
分析原因:
1、连续遇到问题的惰性放弃;
2、遇到不懂baidu、google一下,并有探索精神去归根究底,这也是我为什么决定重新开始博客,继续去总结分析一些开发历程的原因,有问题就必须去深钻问题,否则只能在表面!

3 总结一下

a、最怕的问题是连续遇到问题,永远保持耐心和探索心,去解决一个个问题,方能保持敏锐度,知其然必要知道其所以然!
b、保持google和百度,去查找可能影响不那么大的小问题,也许小问题可以学更多;
c、方案不只有一种,保持积极性去学习改进寻找更好的那一个!

扫描二维码关注公众号,回复: 3230884 查看本文章

猜你喜欢

转载自blog.csdn.net/xinquanv1/article/details/77745172