2012-03-31 1 views
1

Wie in XSD-Schema tun Sequenz von Elementen mit unterschiedlichen Namen und einem Basistyp?XSD-Elemente mit Basistyp

<function name="test"> 
    <set name="name" value="StackMommy" /> 
    <log message="hello, ${name}" /> 
</function> 

Ich möchte mit jaxb erzeugt pojo Klassen einige dieser:

class Function { 
    List<Command> commands; 
} 
+0

http://jaxb.java.net/guide/Mapping_interfaces.html helfen könnte. – Barend

Antwort

2

Die @XmlElementRef Anmerkung ist, was Sie in diesem Anwendungsfall suchen. Es wird verwendet, um das Konzept der Substitutionsgruppen abzubilden.

Funktion

Die commands Eigenschaft wird mit @XmlElementRef kommentiert. Das bedeutet, dass wir diese Eigenschaft basierend auf den XML-Elementen auffüllen werden, die den Unterklassen Command von @XmlRootElement oder @XmlElementDecl zugeordnet sind.

package forum9952449; 

import java.util.List; 
import javax.xml.bind.annotation.*; 

@XmlRootElement 
class Function { 
    @XmlElementRef 
    List<Command> commands; 
} 

Befehl

Die @XmlSeeAlso Anmerkung zu den Unterklassen Punkt verwendet wird. Dies ist kein notwendiger Schritt, aber es bedeutet, dass wir die Subklassen beim Bootstrap JAXBContext nicht explizit übergeben müssen.

package forum9952449; 

import javax.xml.bind.annotation.XmlSeeAlso; 

@XmlSeeAlso({Set.class, Log.class}) 
public abstract class Command { 

} 

Set

Wir brauchen diese Klasse mit @XmlRootElement zu annotieren. In diesem Fall lautet der Name des Stammelements standardmäßig set.

package forum9952449; 

import javax.xml.bind.annotation.*; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Set extends Command { 

    @XmlAttribute 
    private String name; 

    @XmlAttribute 
    private String value; 

} 

Log

Wieder annotieren wir diese Unterklasse mit @XmlRootElement.

package forum9952449; 

import javax.xml.bind.annotation.*; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Log extends Command { 

    @XmlAttribute 
    private String message; 

} 

Demo

package forum9952449; 

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Function.class); 

     File xml = new File("src/forum9952449/input.xml"); 
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     Function function = (Function) unmarshaller.unmarshal(xml); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(function, System.out); 
    } 

} 

Input/Output

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<function> 
    <set value="StackMommy" name="name"/> 
    <log message="hello, ${name}"/> 
</function> 

function.xsd

Der entsprechende XML-schem a würde ungefähr wie folgt aussehen. Da Sie von einem Objektmodell mit JAXB ausgehen können, brauchen Sie es nicht wirklich.

<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    <xs:element name="function" type="function"/> 

    <xs:element name="command" type="command"/> 

    <xs:element name="set" type="set" 
     substitutionGroup="command"/> 

    <xs:element name="log" type="log" 
     substitutionGroup="command"/> 

    <xs:complexType name="function"> 
     <xs:sequence> 
      <xs:element ref="command"/> 
     </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="command" abstract="true"> 
     <xs:sequence/> 
    </xs:complexType> 

    <xs:complexType name="set"> 
     <xs:complexContent> 
      <xs:extension base="command"> 
       <xs:attribute name="name" type="xs:string"/> 
       <xs:attribute name="value" type="xs:string"/> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 

    <xs:complexType name="log"> 
     <xs:complexContent> 
      <xs:extension base="command"> 
       <xs:attribute name="message"/> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 

</xs:schema> 

Weitere Informationen