我被这个 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>
这是我需要从 Java 创建的完整 xml 文件的示例:SUBMISSION_REQUEST.xml .
这是我所做的总结:
- 从涉及的两个 XSD 文件生成 Java 类。涉及的两个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
- 创建了一个单元测试,根据 SUBMISSION_REQUEST.xml 中的值设置 GovTalkMessage 对象的值
- (这是我遇到问题的地方)。设置 Body 的值,我需要形成 IRenvelope 来完成 xml,但我得到的是一个带有不完整 setter 的 Body 类(没有 IRenvelope)。
主要的 xml 信封是 GovTalkMessage,用于向英国政府的 HMRC 发送消息。似乎 GovTalkMessage 信封已变得可重复使用,它可以通过特别使用 Body 标签来接受不同的消息。
我的难题是,在 Body 标签内,我需要能够将来自 FullPaymentSubmission-2016-v1-2.xsd 的 IRenvelope 作为 XML 架构IRenvelope,并能够在 Java 中设置与此对象关联的值,以便我可以创建整个 xml,如 SUBMISSION_REQUEST.xml 所示
GovTalkMessage 的 XSD 是 envelope-v2-0-HMRC.xsd。你会看到匿名Body类型下的是anyAttribute和any。但我需要的是 IRenvelope。
为了更清楚地解释,我已经为 envelope-v2-0-HMRC.xsd 生成了 Java 类,并为我提供了 GovTalkMessage.java,这是我需要为其设置值的主要等效 xml GovTalkMessage 信封。
以下是我使用的 xjc 命令:
xjc -p com.rti.rim2016.v1_2.envelope 信封-v2-0-HMRC.xsd
xjc -p com.rti.rim2016.v1_2.fps FullPaymentSubmission-2016-v1-2.xsd
主要问题在于 GovTalkMessage“Body”元素,该元素使用 ##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>
为envelope-v2-0-HMRC.xsd生成了相应的Java类,并得到了GovTalkMessage.java的代码(我只提供了与“body”元素相关的片段)。
显然没有 setter 方法来重定向设置与 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);
我尝试使用从 FullPaymentSubmission-2016-v1-2.xsd 生成的 IRenvelope java 类实例设置 getAny,但出现以下错误:
错误:
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)
我希望有人能帮助我阐明如何正确解决这个问题。
最佳答案
回答
您应该只需要使用两个生成的包在冒号分隔的 String
上创建您的 JAXBContext
:
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>
关于java - 使用 XSD 中的元素 "anyAttribute"和 "any"将 XML 编码为 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28361603/