Выделение XML в Java с элементами "anyAttribute" и "any" в XSD

Я застрял с этой проблемой XSD и JAXB... Пожалуйста, помогите мне...

Что мне нужно сделать, это полностью сгенерировать XML ниже.

<?xml version="1.0"?>
<GovTalkMessage xmlns="http://www.govtalk.gov.uk/CM/envelope">
        ....
    <Body>
        <IRenvelope xmlns="http://www.govtalk.gov.uk/taxation/PAYE/RTI/FullPaymentSubmission/15-16/1">
            ....
        </IRenvelope>
    </Body>
</GovTalkMessage>

Вот пример полного XML-файла, который мне нужно создать из Java: SUBMISSION_REQUEST.xml.

Вот краткое изложение того, что я сделал:

  1. Сгенерировал классы Java из двух задействованных файлов XSD. Используются два XSD-файла: envelope-v2-0-HMRC.xsd - ссылка на файл: https:// drive.google.com/file/d/0Bwota60eLfeIN1duSGVhTE8xOWM/view?usp=sharing FullPaymentSubmission-2016-v1-2.xsd - ссылка на файл: https:// drive.google.com/file/d/0Bwota60eLfeIbUtMN1RaMmt0LWM/view?usp=sharing
  2. Создан модульный тест, устанавливающий значения для объекта GovTalkMessage на основе значений из SUBMISSION_REQUEST.xml
  3. (Это где у меня была проблема). Устанавливая значения для Body, мне нужно сформировать IRenvelope для завершения xml, но я получил класс Body с неполными установщиками (нет IRenvelope).

Основным xml-конвертом является GovTalkMessage, который используется для отправки сообщений в HMRC правительства Великобритании. Похоже, что конверт GovTalkMessage был повторно использован, что позволяет принимать различные сообщения, в частности, с помощью тега Body.

Моя дилемма заключается в том, что внутри тега Body мне нужно иметь возможность разместить IRenvelope, исходящий из FullPaymentSubmission-2016-v1-2.xsd, в качестве XML-схемы для IRenvelope, и иметь возможность устанавливать значения, связанные с этим объектом в Java, чтобы Я мог бы создать весь XML, как видно на SUBMISSION_REQUEST.xml

XSD для GovTalkMessage - это envelope-v2-0-HMRC.xsd. Вы увидите, что под анонимным типом Body является anyAttribute и any. но мне нужен IRenvelope.

Для более ясного объяснения я сгенерировал Java-классы для envelope-v2-0-HMRC.xsd и дал мне GovTalkMessage.java, который является основным эквивалентом конверта xov GovTalkMessage, для которого мне нужно установить значения.

Ниже приведены команды xjc, которые я использовал:

xjc -p com.rti.rim2016.v1_2.envelope envelope-v2-0-HMRC.xsd

xjc -p com.rti.rim2016.v1_2.fps FullPaymentSubmission-2016-v1-2.xsd

Основная проблема связана с элементом "Body" GovTalkMessage, который использует ##any и xsd:anyAttribute.

    <xsd:element minOccurs="0" maxOccurs="1" name="Body">
      <xsd:complexType>
        <xsd:sequence>
          <xsd:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
        <xsd:anyAttribute namespace="##any" processContents="strict"/>
      </xsd:complexType>
    </xsd:element>

Сгенерировал соответствующие Java-классы для envelope-v2-0-HMRC.xsd и получил код для GovTalkMessage.java (я предоставил только фрагмент, связанный с элементом body).

Очевидно, что не было метода установки для перенаправления значений, связанных с IRenvelope, чтобы я мог завершить сборку XML.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "envelopeVersion",
    "header",
    "govTalkDetails",
    "body"
})
@XmlRootElement(name = "GovTalkMessage", namespace = "http://www.govtalk.gov.uk/CM/envelope")
public class GovTalkMessage {

    @XmlElement(name = "Body", namespace = "http://www.govtalk.gov.uk/CM/envelope")
    protected GovTalkMessage.Body body;
    ....

    public GovTalkMessage.Body getBody() {
        return body;
    }

    /**
     * Sets the value of the body property.
     * 
     * @param value
     *     allowed object is
     *     {@link GovTalkMessage.Body }
     *     
     */
    public void setBody(GovTalkMessage.Body value) {
        this.body = value;
    }

Я вижу только те атрибуты getAny и getOtherAttributes, с которыми я играл и не работал.

    //Body
    Body body = new Body();
    IRenvelope irEnvelope = new IRenvelope();
    body.getAny().add(irEnvelope);
    govTalkMessage.setBody(body);

Я попытался установить getAny с экземпляром Java-класса IRenvelope, сгенерированным из FullPaymentSubmission-2016-v1-2.xsd, но получил ошибку ниже:

Ошибка:

javax.xml.bind.MarshalException
 - with linked exception:
[com.sun.istack.internal.SAXException2: class com.rti.rim2016.v1_2.fps.generated.IRenvelope nor any of its super class is known to this context.
javax.xml.bind.JAXBException: class com.upraxis.rti.rim2016.v1_2.fps.generated.IRenvelope nor any of its super class is known to this context.]
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:311)
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:236)
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:116)

Я надеюсь, что кто-то может помочь мне пролить свет на то, как правильно решить эту проблему.

1 ответ

Ответ

Вам просто нужно создать свой JAXBContext на двоеточии String с двумя сгенерированными пакетами:

JAXBContext jc = JAXBContext.newInstance("com.rti.rim2016.v1_2.fps:com.rti.rim2016.v1_2.envelope");

Демонстрационный код

Затем, когда я бегу:

import javax.xml.bind.*;
import com.rti.rim2016.v1_2.fps.*;
import com.rti.rim2016.v1_2.envelope.GovTalkMessage;
import com.rti.rim2016.v1_2.envelope.GovTalkMessage.Body;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance("com.rti.rim2016.v1_2.fps:com.rti.rim2016.v1_2.envelope");

        GovTalkMessage govTalkMessage = new GovTalkMessage();

        Body body = new Body();
        IRenvelope irEnvelope = new IRenvelope();
        body.getAny().add(irEnvelope);
        govTalkMessage.setBody(body);

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

}

Я получаю следующее в качестве вывода:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:GovTalkMessage xmlns="http://www.govtalk.gov.uk/taxation/PAYE/RTI/FullPaymentSubmission/15-16/1" xmlns:ns2="http://www.govtalk.gov.uk/CM/envelope" xmlns:ns3="http://www.w3.org/2000/09/xmldsig#">
    <ns2:Body>
        <IRenvelope/>
    </ns2:Body>
</ns2:GovTalkMessage>
Другие вопросы по тегам