java下处理一个xml文档,常常使用DOM(Document Object Model,SAX(Simple API for XML)什么的,但是,当文档很复杂的时候,我们其实可以使用一些偷懒的方法的,JAXB是我最习惯的偷懒大法.当文档大小适中(100MB下都是小文件,嗯.),直接把这个文档丢jaxb,然后从jaxb中寻找需要的信息.实在是一个好办法. 但是,有时候,我们会遇到一些奇怪的格式. 比如下面这么段XML.

<xxx>
here is <italic>a</italic> sample of <bold>XmlMixed</bold> type.
</xxx>

那么,它的 xsd 可能会是像这样的:

<complexType>
    <complexContent>
        <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
            <choice maxOccurs="unbounded" minOccurs="0">
                <element ref="{http://xxx/schema}italic"/>
                <element ref="{http://xxx/schema}bold"/>
            </choice>
        </restriction>
    </complexContent>
</complexType>

而这段xsd通过xjc可能会生成如下的一些代码:

    @XmlElementRefs({
        @XmlElementRef(name = "bold", namespace = "http://xxx/schema", 
                type = JAXBElement.class, 
                required = false),
        @XmlElementRef(name = "italic", namespace = "http://xxx/schema", 
                type = JAXBElement.class, 
                required = false)
    })
    @XmlMixed
    protected List<Object> content;

然后在需求的需要下,我们必须解析前面那个前面的那个"here is a sample of XmlMixed type."这段信息. 而万能的google这次貌似不怎么灵了,很多人都提到了XmlMixed这个神秘生物,却没有找到谁来详细说说这个东西是怎么整的,或许大家都觉得这东西很简单,没啥好说的吧,连官方文档都没给个sample code...经过一些猜测后(好吧我各种菜的),终于解析出来了.以后自己可以复习下.若能帮助到别人,当然更好了.

若哪位有更多详细的信息,也先多谢指教.

解决

以前文的例子为例,我们可以得到一个 List<object> content, 这个 content 中包含3种类型的数据,1是普通的String类型,2是名叫bold的,JAXBElement类型,3是名叫italic的JAXBElement类型.

在类型上,其实就只有两种数据: 1. String , 2. JAXBElement

那么,我们可以使用类似于这样的一个方法来搞定.

public static String mixContentParse(List<Object> content){
    String value = "";
    for(Object cc: content){
        if(cc.getClass().equals(JAXBElement.class)){
            // italic or bold
            value += ((JAXBElement)cc).getValue();
        }else if(cc.getClass().equals(String.class)){
            // general String type
            value += ((String)cc);
        }else {
            System.out.println("There may sth wrong ?");
        }
    }
    return value;
}

这个方法就是获得 这个标签下的所有文本信息.然后返回为一个 String. 写完后感觉的确很方便的,可惜没学过这个的结果就是,感觉常识都不知道..囧个


刚才师兄吐槽了下我的写法,然后给了个比较优美的写法

public static String mixContentParse(List<Object> content){
    String value = "";
    for(Object cc: content){
        if(JAXBElement.class.isInstance(cc)){
            // italic or bold
            value += ((JAXBElement<?>)cc).getValue();
        }else if(String.class.isInstance(cc)){
            // general String type
            value += (String)cc;
        }else{
            System.out.println("there may sth wrong?");
        }
    }
    return value;
}

Yu

Ideals are like the stars: we never reach them, but like the mariners of the sea, we chart our course by them.

7 Comments

Leniy · August 9, 2013 at 20:59

Google Chrome 30.0.1573.2 Google Chrome 30.0.1573.2 Windows 7 Windows 7

我不喜欢java的地方就在于,什么都JAXBElement.class.isInstance这样的好长。我喜欢代码短的,即使没有语义型,如a[i]->p

    yu · August 9, 2013 at 21:50

    Google Chrome 28.0.1500.71 Google Chrome 28.0.1500.71 GNU/Linux x64 GNU/Linux x64

    表示对代码风格不发表看法.代码设计者,教程是什么风格,我也会尽可能是那种风格..
    所以我的Java和C/C++简直不像是一个人写的

      Leniy · August 11, 2013 at 16:33

      Google Chrome 30.0.1573.2 Google Chrome 30.0.1573.2 Windows 7 Windows 7

      偶的代码,除了语言要求的语法,别的几乎风格是一样的

92原创 · August 5, 2013 at 14:44

Google Chrome 28.0.1500.72 Google Chrome 28.0.1500.72 Windows 7 Windows 7

这代码我能看懂了,呵呵

    yu · August 5, 2013 at 20:07

    Google Chrome 28.0.1500.71 Google Chrome 28.0.1500.71 GNU/Linux x64 GNU/Linux x64

    java的类,方法,变量什么大多会取一些很长的名字,所以一般代码本身都带有自解释功能.
    从这个角度上说,java还是可以的

小怪兽 · July 15, 2013 at 09:42

Google Chrome 21.0.1180.89 Google Chrome 21.0.1180.89 Windows XP Windows XP

来支持一个。。

    yu · July 15, 2013 at 10:19

    Google Chrome 28.0.1500.71 Google Chrome 28.0.1500.71 GNU/Linux x64 GNU/Linux x64

    这个评论很正常啊,为毛被丢判定去了

Leave a Reply to yu Cancel reply

Your email address will not be published. Required fields are marked *