通过继承层次结构进行解析

时间:2014-10-15 21:08:27

标签: java inheritance jaxb xsd

我有一些场景层次结构,其中节点以时尚方式相互继承

<xs:complexType name="XNode">
    <xs:attribute name="layer" type="xs:integer" use="optional"/>
</xs:complexType>

<xs:complexType name="XStyleable">
    <xs:complexContent>
        <xs:extension base="XNode">
            <xs:attribute name="id" type="xs:string" use="optional"/>
            <xs:attribute name="class" type="xs:string" use="optional"/>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

我想要的地方

<xs:complexType name="XGroup">
    <xs:complexContent>
        <xs:extension base="XStyleable">
            <xs:sequence>
                <xs:element name="XNode" type="XNode" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

不仅可以识别XNode,还可以识别扩展XNode的所有内容,因此具有类似

的结构
<XGroup>
    <XNode/>
    <XGroup/>
    <XNode/>
    <XStyleable/>
</XGroup>

将导致XGroup的实例包含List中的三个实例(两个XNode,一个XGroup和一个XStyleable)的列表,我可以测试它的原始类上的每个实例,并在演员之后决定它的信仰。

我知道我能做到

<xs:complexType name="XGroup">
    <xs:complexContent>
        <xs:extension base="XStyleable">
            <xs:sequence>
                <xs:element name="XNode" type="XNode" minOccurs="0" maxOccurs="unbounded"/>
                <xs:element name="XGroup" type="XGroup" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

但是遗漏了父母内部节点原始顺序的信息,我想保留这些信息。

你有什么建议如何解决这个问题?我真的不想写我自己的解析器只是为了得到这种行为:(

1 个答案:

答案 0 :(得分:2)

您可以执行以下操作:

XML Schema(schema.xsd)

您可以在XML Schema中利用替换组,并将其设置如下:

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

    <xs:element name="XNode" type="XNode"/>
    <xs:complexType name="XNode">
        <xs:attribute name="layer" type="xs:integer" use="optional"/>
    </xs:complexType>

    <xs:element name="XStyleable" type="XStyleable" substitutionGroup="XNode"/>
    <xs:complexType name="XStyleable">
        <xs:complexContent>
            <xs:extension base="XNode">
                <xs:attribute name="id" type="xs:string" use="optional"/>
                <xs:attribute name="class" type="xs:string" use="optional"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="XGroup" type="XGroup" substitutionGroup="XNode"/>
    <xs:complexType name="XGroup">
        <xs:complexContent>
            <xs:extension base="XStyleable">
                <xs:sequence>
                    <xs:element ref="XNode"  minOccurs="0" maxOccurs="unbounded"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

</xs:schema>

生成Java模型

运行以下内容将从XML Schema生成Java模型。由于XML Schema中没有目标名称空间,因此默认程序包名称为generated

xjc schema.xsd

演示代码

<强>演示

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

public class Demo {

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

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("input.xml");
        JAXBElement<XGroup> je = (JAXBElement<XGroup>) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        marshaller.marshal(je, System.out);
    }

}

<强> input.xml中/输出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<XGroup>
    <XNode/>
    <XGroup/>
    <XNode/>
    <XStyleable/>
</XGroup>

更多信息

我在博客上写了更多关于此的内容: