Попробуйте с такой схемой:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" attributeFormDefault="unqualified">
<xsd:element name="Subscribers" type="SubscriberType"/>
<xsd:element name="Subscriber" type="SubscriberInformation" />
<xsd:complexType name="SubscriberType">
<xsd:sequence>
<xsd:element ref="Subscriber" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
Я считаю, что с вашей схемой происходит следующее: контекст JAXB знает класс для SubscriberType
и SubscriberInformation
. Если вы дадите ему XML-документ с корневым элементом <Subscribers>
, он знает, что он должен разархивировать класс для SubscriberType
. Однако, если вы дадите ему XML-документ с корневым элементом <Subscriber>
, он обычно не найдет определение этого элемента в классе ObjectFactory
, созданном XJC. Но так как вы использовали метод unmarshal
, который принимает второй аргумент, а именно класс, который вы ожидаете, вы сказали демаршаллеру, что он должен интерпретировать свой ввод как SubscriberType
. Результатом будет пустой SubscriberType
экземпляр.
Теперь, поскольку вы перебираете элементы <Subscriber>
один за другим (по крайней мере, я так понимаю, вы собираетесь это сделать), для unmarshaller кажется, что он получает XML-документы с этим именем root элемент. Он не будет жаловаться на то, что не нашел это определение, поскольку вы решили выяснить тип с помощью аргумента класса. Но в тот момент, когда вы присоединяете схему для проверки, все выходит из строя. Валидатор не знает, что вы находитесь внутри элемента <Subscribers>
. Он ожидает полный документ XML. Таким образом, он ищет объявление элемента для <Subscriber>
, но получается пустым, поскольку этот элемент определен только в сложном типе. Это не глобальное определение элемента (то есть одно под корнем схемы).
Итак, две вещи здесь. Один из них - определить элемент <Subscriber>
, как показано выше, а затем ссылаться на него в ваших сложных типах. Другой способ - изменить свой не маршальный вызов на unmarshal(streamReader, SubscriberInformation.class)
, чтобы вернуть правильный тип объекта. Также обратите внимание на наличие бесконечных циклов или неверного демаршаллинга, поскольку ваш вызов streamReader.next()
находится в состоянии и может не сработать.
Написание схем с учетом JAXB требует определенного стиля. В общем, лучше всего определять элементы глобально, а затем ссылаться на них. Определите элемент локально внутри сложного типа, только если он обязательно должен оставаться там инкапсулированным.
Извините за многословный ответ, я не очень хорошо проснулся:)