首页 文章

没有属性的JAXB元素

提问于
浏览
2

我正在使用JAXB,需要生成如下的XML代码:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><!--Created with JFLAP 6.4.-->
<structure>
    <type>fa</type>
    <automaton>
        <!--The list of states.-->
        <state id="0" name="q0">
            <x>160.0</x>
            <y>151.0</y
            <initial/>                 <!-- This what I want-->
        </state>
        <state id="1" name="q1">
            <x>369.0</x>
            <y>94.0</y>
            <final/>                   <!-- This what I want-->
        </state>
        <!--The list of transitions.-->
        <transition>
            <from>0</from>
            <to>1</to>
            <read>a</read>
        </transition>
    </automaton>
</structure>

正如你所看到的,我想知道如何在没有@XmlAttribute的情况下创建一个简单的@XmlElement,但是在我的代码中,我得到了:

private boolean initial = false;
private boolean final   = false;

@XmlElement(name="initial")
public void setInitial(boolean val) {
    this.initial = val;
}

@XmlElement(name="final")
public void setFinal(boolean val) {
    this.final = val;
}

这样,我得到了这样的XML:

<state id="0" name="q0">
        <x>0.0</x>
        <y>0.0</y>
        <final>false</final>
        <initial>true</initial>
</state>
<state id="1" name="q1">
        <x>0.0</x>
        <y>0.0</y>
        <final>true</final>
        <initial>false</initial>
</state>

有谁知道怎么做?

2 回答

  • 0

    您可以执行以下操作并利用 XmlAdapterBoolean 转换为空对象以获取所需的XML表示形式 .

    Java模型

    Root

    该属性是 boolean ,但我们将使字段 Boolean ,以便我们可以应用 XmlAdapter . 我们还将指定我们希望JAXB映射到该字段(请参阅:http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html) .

    import javax.xml.bind.annotation.*;
    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    
    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Root {
    
        @XmlJavaTypeAdapter(BooleanAdapter.class)
        private Boolean foo = false;
    
        @XmlJavaTypeAdapter(BooleanAdapter.class)
        private Boolean bar = false;
    
        public boolean isFoo() {
            return foo;
        }
    
        public void setFoo(boolean foo) {
            this.foo = foo;
        }
    
        public boolean isBar() {
            return bar;
        }
    
        public void setBar(boolean bar) {
            this.bar = bar;
        }
    
    }
    

    BooleanAdapter

    import javax.xml.bind.annotation.adapters.XmlAdapter;
    
    public class BooleanAdapter extends XmlAdapter<BooleanAdapter.AdaptedBoolean, Boolean> {
    
        public static class AdaptedBoolean {
        }
    
        @Override
        public Boolean unmarshal(AdaptedBoolean v) throws Exception {
            return null != v;
        }
    
        @Override
        public AdaptedBoolean marshal(Boolean v) throws Exception {
            if(v) {
                return new AdaptedBoolean();
            } else {
                return null;
            }
        }
    
    }
    

    演示代码

    下面是一些演示代码,您可以运行以查看一切正常 .

    Demo

    import javax.xml.bind.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Root.class);
    
            Root foo = new Root();
            foo.setFoo(true);
            foo.setBar(false);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(foo, System.out);
        }
    
    }
    

    Output

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <root>
        <foo/>
    </root>
    
  • 0

    您可以通过设置空字符串来伪造空节点,为此您需要将 boolean s转换为 String s .

    @XmlRootElement
    public static  class Structure {
        @XmlElement String type;
        @XmlElement Automaton automaton;
        public Structure() { automaton = new Automaton(); }
        Structure(String t) { this(); type = t; }
    }
    
    public static class Automaton {
        @XmlElement List<State> state;
        public Automaton() { state = new ArrayList<>(); }
        State addState(State s) {state.add(s); return s;};
    }
    
    public static class State {
        @XmlAttribute String id, name;
        @XmlElement double x, y;
        @XmlElement String initial;
        @XmlElement(name="final") String final_;
        public State() {};
        State(String id, String n, double x, double y)
        {this.id = id; name = n; this.x = x; this.y = y;};
    }
    

    创建一些数据并封送它:

    @Test
    public void jaxbEmptyEmlements() throws JAXBException {
        JAXBContext c = JAXBContext.newInstance(Structure.class);
        Marshaller m = c.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        Structure o = new Structure("fa");
        o.automaton.addState(new State("0", "q0", 160d, 151d)).initial = "";
        o.automaton.addState(new State("1", "q1", 369d, 94d)).final_ = "";
        m.marshal(o, System.out);
    }
    

    这将输出

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <structure>
        <type>fa</type>
        <automaton>
            <state id="0" name="q0">
                <x>160.0</x>
                <y>151.0</y>
                <initial></initial>
            </state>
            <state id="1" name="q1">
                <x>369.0</x>
                <y>94.0</y>
                <final></final>
            </state>
        </automaton>
    </structure>
    

    请注意 <initial></initial><initial/> 相同, final 相同 .

    或者,您可以重新考虑状态类型的节点并创建一个元素<state-type>并使用值enum设置它,例如enum StateType {INITIAL,FINAL}或者只是将其设置为字符串initial或final .

    EDIT
    enter image description here

相关问题