Я полностью новичок в архитектуре JAXB. Но вот то, что я пытаюсь сделать, и где застрял в двух словах.JAXB, Unmarshalling и Marshalling против класса Wrapper.
Я создаю веб-приложение, в котором клиент сначала зарегистрирует свой xsd, а затем отправит свои данные xml/json в соответствии с xsd.
Для регистрации XSD, я использую XJC (не как Maven плагин, но вместо того, чтобы из самого кода Java:
SchemaCompiler sc = XJC.createSchemaCompiler();
File schemaFile = new File(schemaPath);
InputSource is = new InputSource(new FileInputStream(schemaFile));
is.setSystemId(schemaFile.getAbsolutePath());
sc.parseSchema(is);
S2JJAXBModel model = sc.bind();
JCodeModel jCodeModel = model.generateCode(null, null);
jCodeModel.build(new File(outputDirectory));
По XSD выглядит как:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Metadata" type="Metadata" />
<xsd:complexType name="Metadata">
<xsd:sequence>
<xsd:element name="MicroscopeStagePosition"
type="MicroscopeStagePosition" maxOccurs="1" minOccurs="1">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="MicroscopeStagePosition">
<xsd:sequence>
<xsd:element name="Start" type="xsd:string"/>
<xsd:element name="End" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Я создавая JAXB annoted классы POJO из вышеизложенного и 2 классов созданы являются:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Metadata", propOrder = {
"microscopeStagePosition"
})
public class Metadata {
@XmlElement(name = "MicroscopeStagePosition", required = true)
protected MicroscopeStagePosition microscopeStagePosition;
public MicroscopeStagePosition getMicroscopeStagePosition() {
return microscopeStagePosition;
}
public void setMicroscopeStagePosition(MicroscopeStagePosition value) {
this.microscopeStagePosition = value;
}
}
и
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MicroscopeStagePosition", propOrder = {
"start",
"end"
})
public class MicroscopeStagePosition {
@XmlElement(name = "Start", required = true)
protected String start;
@XmlElement(name = "End", required = true)
protected String end;
public String getStart() {
return start;
}
public void setStart(String value) {
this.start = value;
}
public String getEnd() {
return end;
}
public void setEnd(String value) {
this.end = value;
}
}
Теперь моя идея иметь общий аннотированный класс, который будет обертка вокруг этого выше классов, которые будут созданы в режиме реального времени (этот класс создается в реальном времени и, следовательно, может иметь все, что должно быть).
Проблема в том, что я не знаю, какой xsd придет и, следовательно, rootelement не поможет. Поэтому я думал создать оболочку вокруг созданного класса JAXB, а затем заниматься только этим оберточным классом во всем API.
я создал ниже класса в реальном времени:
public class MyModel {
@XmlElement(required = true)
protected Metadata Metadata;
@XmlElement(required = true)
protected MicroscopeStagePosition MicroscopeStagePosition;
}
Можно ли Unmarshell на входящий XML, основанный на этом классе обертке. Обратите внимание, что входящий XML не может быть принужден иметь в нем корневой элемент MyModel. Таким образом, я пытаюсь создать корневой JAXBElement, а затем присвоить его класса-оболочки:
MyModel je = new MyModel();
JAXBContext jaxbContext = JAXBContextFactory.createContext(new Class[] {MyModel.class}, null);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
InputStream is = new ByteArrayInputStream(sIncomingMetadataXML.getBytes());
JAXBElement<MyModel> root = jaxbUnmarshaller.unmarshal(new StreamSource(
is), MyModel.class);
je = root.getValue();
если я аннотирования MyModel с @XmlRootElement @XmlAccessorType (XmlAccessType.FIELD) и возвращения драг из моего апи его нулевой дочерний объект XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyModel/>
и если не возникает ошибка:
сообщение тело писателя класса Java Aand MIME тип медиа приложения/XML не был найден.
Так может я создать класс-оболочку, как и выше, и если да, то как ?, или я пропустил совершенно что-то здесь
Обратите внимание, что входящий XML не может быть принудительно иметь в нем корневой элемент MyModel. Почему бы и нет?, Кажется, самый простой способ. Храните встроенный xml (добавьте то, что вам нужно), а затем unmarshal, это вы можете сделать во время выполнения (без сохранения файла) .... –
Хм, хорошо подумал, что это будет быть чистым кодом, но можете ли вы использовать elloborate, как добавить родительский тег к входящему XML без сохранения в файл? –
Я отправил ответ, я делаю это часто, так как, когда я взаимодействую с другой службой (msxml ecc) из java, мне нужно обрабатывать разные заголовки спецификации ecc. Возможно, это занимает немного больше памяти, но у вас гораздо больше контроля над входящими данными ... –