【问题标题】:Create XML Schema for Java with inheritance and Java Interfaces use使用继承和 Java 接口为 Java 创建 XML 模式
【发布时间】:2015-03-31 23:43:57
【问题描述】:

我有这个用于操作这个领域车辆的类集合

这是我的问题:我需要将数据保存(通过解析)到 XML 文件。为此,我必须创建一个 XML Schema (XSD),但在继承和接口方面遇到了困难。

首先,似乎有必要快速解释我的课程:

Vehicle 类是一个抽象类,包含基本属性:

public abstract class Vehicle implements Serializable {

    public enum Stato {
        DISPONIBILE,
        NON_DISPONIBILE
    }

    private String plate;   // targa
    private String mark;    // Marca, Casa Produttrice
    private String model;   // Modello
    private String trim;    // Trim
    private float capacity; // capacità di carico
    // ... other...
    private Stato stato;    // Stato del veicolo
    private String allestimento;

    public Vehicle(){}

    public Vehicle(String plate) {
        this.plate=plate;
    }

    // Get&Set methods 
    // ...
}

现在,例如,汽车

public class Car extends Vehicle implements DrivingPart {

    public Car();

    public Car(String plate) {
        super(plate);
    }

}

...和TrailerTruck

public class TrailerTruck extends Vehicle {

    // TRAILER TRUCK: autocarro
    // Driving Part: Car, Van, Truck
    // Driven part: Trailer (always)

    String plateFront;
    String plateTrailer;

    DrivingPart drivingVehicle;
    Trailer trailerVehicle;

    public TrailerTruck(DrivingPart drivingVehicle, Trailer trailerVehicle) {
        plateFront=drivingVehicle.getPlate();
        plateTrailer=trailerVehicle.getPlate();
        setPlate(plateFront+" - "+plateTrailer);

        this.drivingVehicle=drivingVehicle;
        this.trailerVehicle=trailerVehicle;
    }

    @Override
    public String getAllestimento() {
        return drivingVehicle.getAllestimento()
                +", "+trailerVehicle.getAllestimento();
    }

    // ...
}

好的,这个功能很好。我可以轻松地创建对象 Vehicle:

Vehicle car = new Car("AAA1");
car.setMark("Peugeot");
car.setModel("206");
car.setStato(Stato.DISPONIBILE);
//...

Vehicle truck = new Truck("AAA2");
truck.setMark("Scania");
//...

Vehicle trailer = new Trailer("TTT1");
trailer.setMark("Menci");
//...

Vehicle tt1 = new TrailerTruck((Truck) truck, (Trailer) trailer);
//...

插图结束。对不起,如果我已经住了。

编辑

这是我的解决方案尝试

ShipperXMLSchema.xsd

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="Fleet" type="FleetType"/>


    <xs:complexType name="FleetType">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="Car" type="CarType"/>
            <xs:element name="Van" type="VanType"/>
            <xs:element name="Truck" type="TruckType"/>
            <xs:element name="Trailer" type="TrailerType"/>
            <xs:element name="RoadTractor" type="RoadTractorType"/> 
            <xs:element name="SemiTrailer" type="SemiTrailerType"/>
            <xs:element name="TrailerTruck" type="TrailerTruckType"/>
            <xs:element name="SemiTrailerTruck" type="SemiTrailerTruckType"/>
        </xs:choice>
        <xs:attribute name="shipperName" type="xs:string"/>
    </xs:complexType>


    <xs:complexType name="VehicleType" abstract="true">
        <xs:sequence>
            <xs:element name="plate" type="xs:string" minOccurs="1" />
            <xs:element name="mark" type="xs:string" minOccurs="0" />
            <xs:element name="model" type="xs:string" minOccurs="1" />
            <xs:element name="trim" type="xs:string" />
            <xs:element name="allestimento" type="xs:string" minOccurs="0" />
            <xs:element name="stato" type="State"/>
            <xs:element name="carryingCapacity" type="xs:float" minOccurs="0" />
            <xs:element name="ptt" type="xs:float" minOccurs="0" />
            <xs:element name="weight" type="xs:float" minOccurs="0" />
            <xs:element name="volume" type="xs:float" minOccurs="0" />
            <xs:element name="length" type="xs:float" minOccurs="0" />
            <xs:element name="height" type="xs:float" minOccurs="0" />
            <xs:element name="width" type="xs:float" minOccurs="0" />
            <xs:element name="locazioneAttuale" type="xs:string" minOccurs="0" />
        </xs:sequence>
        <xs:attribute name="id" type="xs:string"/>
    </xs:complexType>



    <!-- Definitions: tipi Car, Van, Truck, Trailer, RoadTractor, SemiTrailer -->

    <xs:complexType name="CarType">
        <xs:complexContent>
            <xs:extension base="VehicleType"/>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="VanType">
        <xs:complexContent>
            <xs:extension base="VehicleType"/>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="TruckType">
        <xs:complexContent>
            <xs:extension base="VehicleType"/>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="TrailerType">
        <xs:complexContent>
            <xs:extension base="VehicleType"/>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="RoadTractorType">
        <xs:complexContent>
            <xs:extension base="VehicleType"/>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="SemiTrailerType">
        <xs:complexContent>
            <xs:extension base="VehicleType"/>
        </xs:complexContent>
    </xs:complexType>



    <!-- Definizione tipo TrailerTruck (autotreno) -->

    <xs:group name="DrivingPart">
        <xs:choice>
            <xs:element name="Car" type="CarType"/>
            <xs:element name="Van" type="VanType"/>
            <xs:element name="Truck" type="TruckType"/>
        </xs:choice>
    </xs:group>

    <xs:complexType name="TrailerTruckType">
        <xs:sequence>
            <xs:group ref="DrivingPart"/>
            <xs:element name="Trailer" type="TrailerType" minOccurs="1" maxOccurs="1"/>
        </xs:sequence>
    </xs:complexType>



    <!-- Definition: SemiTrailerTruck -->

    <xs:complexType name="SemiTrailerTruckType" >
        <xs:sequence>
            <xs:element name="RoadTractor" type="RoadTractorType" minOccurs="1" maxOccurs="1"/>
            <xs:element name="SemiTrailer" type="SemiTrailerType" minOccurs="1" maxOccurs="1"/>
        </xs:sequence>
    </xs:complexType>



    <!-- Others... -->

    <xs:simpleType name="State">
        <xs:restriction base="xs:string">
            <xs:enumeration value="DISPONIBILE"/>
            <xs:enumeration value="NON_DISPONIBILE"/>
        </xs:restriction>
    </xs:simpleType>

</xs:schema>

如果托运人有车队。

Shipper1.xml

<?xml version="1.0" encoding="UTF-8"?>
<Fleet shipperName="Shipper1"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="VehicleXMLSchema.xsd"> 

    <Car id="c1">
        <plate>AAA</plate>
        <mark>Peugeot</mark>
        <model>206</model>
        <trim></trim>
        <allestimento></allestimento>
        <stato>DISPONIBILE</stato>
        <carryingCapacity>0.0</carryingCapacity>
        <ptt>2</ptt>
        <weight>0.0</weight>
        <volume>0.0</volume>
        <length>0.0</length>
        <height>0.0</height>
        <width>0.0</width>
        <locazioneAttuale>Bari</locazioneAttuale>
    </Car>

    <Car>
        <plate>BBB</plate>
        <mark>Peugeot</mark>
        <model>206</model>
        <trim></trim>
        <allestimento></allestimento>
        <stato>DISPONIBILE</stato>
        <carryingCapacity>0.0</carryingCapacity>
        <ptt>2</ptt>
        <weight>0.0</weight>
        <volume>0.0</volume>
        <length>0.0</length>
        <height>0.0</height>
        <width>0.0</width>
        <locazioneAttuale>Bari</locazioneAttuale>
    </Car>

    <Van>
        <plate>CCC</plate>
        <mark>Volvo</mark>
        <model></model>
        <trim></trim>
        <allestimento>frigorifero</allestimento>
        <stato>DISPONIBILE</stato>
        <carryingCapacity>0.0</carryingCapacity>
        <ptt>3</ptt>
        <weight>0.0</weight>
        <volume>0.0</volume>
        <length>0.0</length>
        <height>0.0</height>
        <width>0.0</width>
        <locazioneAttuale>Barletta</locazioneAttuale>
    </Van>

    <Truck id="1">
        <plate>DDD</plate>
        <mark>Scania</mark>
        <model></model>
        <trim></trim>
        <allestimento>Frigo</allestimento>
        <stato>DISPONIBILE</stato>
        <carryingCapacity>0.0</carryingCapacity>
        <ptt>5</ptt>
        <weight>0.0</weight>
        <volume>0.0</volume>
        <length>0.0</length>
        <height>0.0</height>
        <width>0.0</width>
        <locazioneAttuale>Andria</locazioneAttuale>
    </Truck>

    <Trailer id="t1">
        <plate>EEE</plate>
        <mark>Scania</mark>
        <model></model>
        <trim></trim>
        <allestimento>Frigo</allestimento>
        <stato>NON_DISPONIBILE</stato>
        <carryingCapacity>0.0</carryingCapacity>
        <ptt>5</ptt>
        <weight>0.0</weight>
        <volume>0.0</volume>
        <length>0.0</length>
        <height>0.0</height>
        <width>0.0</width>
        <locazioneAttuale>Andria</locazioneAttuale>
    </Trailer>

    <RoadTractor>
        <plate>FFF</plate>
        <mark>Scania</mark>
        <model></model>
        <trim></trim>
        <allestimento>Frigo</allestimento>
        <stato>NON_DISPONIBILE</stato>
        <carryingCapacity>0.0</carryingCapacity>
        <ptt>5</ptt>
        <weight>0.0</weight>
        <volume>0.0</volume>
        <length>0.0</length>
        <height>0.0</height>
        <width>0.0</width>
        <locazioneAttuale>Andria</locazioneAttuale>
    </RoadTractor>

    <SemiTrailer>
        <plate>GGG</plate>
        <mark>Scania</mark>
        <model></model>
        <trim></trim>
        <allestimento>Frigo</allestimento>
        <stato>NON_DISPONIBILE</stato>
        <carryingCapacity>0.0</carryingCapacity>
        <ptt>5</ptt>
        <weight>0.0</weight>
        <volume>0.0</volume>
        <length>0.0</length>
        <height>0.0</height>
        <width>0.0</width>
        <locazioneAttuale>Andria</locazioneAttuale>
    </SemiTrailer>


    <TrailerTruck>
        <Car id="c1">
            <plate>AAA</plate>
            <mark>Peugeot</mark>
            <model>206</model>
            <trim></trim>
            <allestimento></allestimento>
            <stato>DISPONIBILE</stato>
            <carryingCapacity>0.0</carryingCapacity>
            <ptt>2</ptt>
            <weight>0.0</weight>
            <volume>0.0</volume>
            <length>0.0</length>
            <height>0.0</height>
            <width>0.0</width>
            <locazioneAttuale>Bari</locazioneAttuale>
        </Car>
        <Trailer>
            <plate>EEE</plate>
            <mark>Scania</mark>
            <model></model>
            <trim></trim>
            <allestimento>Frigo</allestimento>
            <stato>NON_DISPONIBILE</stato>
            <carryingCapacity>0.0</carryingCapacity>
            <ptt>5</ptt>
            <weight>0.0</weight>
            <volume>0.0</volume>
            <length>0.0</length>
            <height>0.0</height>
            <width>0.0</width>
            <locazioneAttuale>Andria</locazioneAttuale>
        </Trailer>
    </TrailerTruck>


    <SemiTrailerTruck>
        <RoadTractor>
            <plate>STT1</plate>
            <mark>Scania</mark>
            <model></model>
            <trim></trim>
            <allestimento>Frigo</allestimento>
            <stato>NON_DISPONIBILE</stato>
            <carryingCapacity>0.0</carryingCapacity>
            <ptt>5</ptt>
            <weight>0.0</weight>
            <volume>0.0</volume>
            <length>0.0</length>
            <height>0.0</height>
            <width>0.0</width>
            <locazioneAttuale>Andria</locazioneAttuale>
        </RoadTractor>
        <SemiTrailer>
            <plate>ST2</plate>
            <mark>Scania</mark>
            <model></model>
            <trim></trim>
            <allestimento>Frigo</allestimento>
            <stato>NON_DISPONIBILE</stato>
            <carryingCapacity>0.0</carryingCapacity>
            <ptt>5</ptt>
            <weight>0.0</weight>
            <volume>0.0</volume>
            <length>0.0</length>
            <height>0.0</height>
            <width>0.0</width>
            <locazioneAttuale>Andria</locazioneAttuale>
        </SemiTrailer>
    </SemiTrailerTruck>

</Fleet>

通过这个实现,我可以在 Java 中操作 Car、Van、Truck、Trailer、RoadTractor 和 SemiTrailer 类......但不能操作复杂的 TrailerTruck 和 SemiTrailerTruck 类。 我需要一个包含继承和接口的不同 XSD。但我不知道怎么做。

【问题讨论】:

  • 你试过using Google吗?
  • @BoristheSpider 我试过了,但我发现了问题。为什么要重新发明轮子?无论如何,我用解决方案编辑了我的问题,但还是不行。
  • 你似乎有一个硬编码的String type 而不是 XML 继承,就像我给你的链接一样。您需要按照链接中的说明使用xs:extension。 XML 中没有“接口”的概念,因为它是数据描述符而不是行为 - 但您应该能够轻松地为每个具体类型定义一个类型并让 JAXB 处理它。
  • 你看我的编辑...你会改变什么?
  • 看起来好多了,有什么问题?

标签: java xml inheritance xsd xml-parsing


【解决方案1】:

我找到了问题的答案。

这是我的 XML 架构。 VehicleXmlSchema.xsd

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="Fleet" type="FleetType"/>

    <xs:complexType name="FleetType">
        <xs:choice maxOccurs="unbounded">
            <xs:element ref="Car"/>
            <xs:element ref="Van"/>
            <xs:element ref="Truck"/>
            <xs:element ref="Trailer"/>
            <xs:element ref="RoadTractor"/> 
            <xs:element ref="SemiTrailer"/>
            <xs:element ref="TrailerTruck"/>
            <xs:element ref="SemiTrailerTruck"/>
        </xs:choice>
        <xs:attribute name="shipperName" type="xs:string"/>
    </xs:complexType>


    <xs:complexType name="VehicleType" abstract="true">
        <xs:sequence minOccurs="0">
            <xs:element name="plate" type="xs:string" minOccurs="1" />
            <xs:element name="mark" type="xs:string" minOccurs="1" />
            <xs:element name="model" type="xs:string" minOccurs="1" />
            <xs:element name="trim" type="xs:string" minOccurs="0" />
            <xs:element name="allestimento" type="xs:string" minOccurs="0" />
            <xs:element name="stato" type="State" minOccurs="1"/>
            <xs:element name="carryingCapacity" type="xs:float" minOccurs="0" />
            <xs:element name="ptt" type="xs:float" minOccurs="0" />
            <xs:element name="weight" type="xs:float" minOccurs="0" />
            <xs:element name="volume" type="xs:float" minOccurs="0" />
            <xs:element name="length" type="xs:float" minOccurs="0" />
            <xs:element name="height" type="xs:float" minOccurs="0" />
            <xs:element name="width" type="xs:float" minOccurs="0" />
            <xs:element name="locazioneAttuale" type="xs:string" minOccurs="0" />
        </xs:sequence>
        <xs:attribute name="id" type="xs:ID"/>
        <xs:attribute name="refid" type="xs:IDREF"/>
    </xs:complexType>


    <!-- Car, Van, Truck, Trailer, RoadTractor, SemiTrailer -->

    <xs:element name="Car">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="VehicleType"/>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>

    <xs:element name="Van">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="VehicleType"/>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>

    <xs:element name="Truck">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="VehicleType"/>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>

    <xs:element name="Trailer">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="VehicleType"/>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>

    <xs:element name="RoadTractor">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="VehicleType"/>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>

    <xs:element name="SemiTrailer">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="VehicleType"/>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>


    <!-- TrailerTruck -->

    <xs:group name="DrivingPart">
        <xs:choice>
            <xs:element ref="Car"/>
            <xs:element ref="Van"/>
            <xs:element ref="Truck"/>
        </xs:choice>
    </xs:group>

    <xs:element name="TrailerTruck">
        <xs:complexType>
            <xs:sequence>
                <xs:group ref="DrivingPart"/>
                <xs:element ref="Trailer" minOccurs="1" maxOccurs="1"/>
            </xs:sequence>
        </xs:complexType>

    </xs:element>


    <!-- SemiTrailerTruck -->

    <xs:element name="SemiTrailerTruck">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="RoadTractor" minOccurs="1" maxOccurs="1"/>
                <xs:element ref="SemiTrailer" minOccurs="1" maxOccurs="1"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>


    <!-- Altre definizioni -->

    <xs:simpleType name="State">
        <xs:restriction base="xs:string">
            <xs:enumeration value="DISPONIBILE"/>
            <xs:enumeration value="NON_DISPONIBILE"/>
        </xs:restriction>
    </xs:simpleType>

</xs:schema>

如您所见,更改 complexType vehicleType 就足够了:

  1. 向内部序列添加属性minOccurs="0"
  2. 添加属性:
    • &lt;xs:attribute name="id" type="xs:ID"/&gt;
    • &lt;xs:attribute name="refid" type="xs:IDREF"/&gt;

而且,在 XML 文件中我可以这样做:

<Car id="car1">
    <plate>AAA</plate>
    <mark>Peugeot</mark>
    <model>206</model>
    <!-- bla bla -->
</Car>

<Truck id="truck1">
    <plate>DDD</plate>
    <mark>Scania</mark>
    <model></model>
    <!-- bla bla -->
</Truck>

<Trailer id="trailer1">
    <plate>EEE</plate>
    <mark>Scania</mark>
    <model></model>
    <!-- bla bla -->
</Trailer>

<TrailerTruck>
    <Car refid="car1"/>
    <Trailer refid="trailer1"/>
</TrailerTruck>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2020-08-23
    相关资源
    最近更新 更多