Java:未在生成的XML中获得名称空间
我必须在Java Maven项目中从Java对象构建XML文件。 我有一个带有XML注释的名为CrossIndustryInvoice的课程。
@Data
@Builder
@AllArgsConstructor @NoArgsConstructor
@XmlRootElement(name="CrossIndustryInvoice", namespace = NamespaceMapper.RSM_URI)
@XmlAccessorType(XmlAccessType.FIELD)
public
class CrossIndustryInvoice {
@XmlElement(name = "ExchangedDocumentContext", namespace = NamespaceMapper.RSM_URI)
private ExchangedDocumentContext exchangedDocumentContext;
@XmlElement(name = "ExchangedDocument", namespace = NamespaceMapper.RSM_URI)
private ExchangedDocument exchangedDocument;
@XmlElement(name = "SupplyChainTradeTransaction", namespace = NamespaceMapper.RSM_URI)
private SupplyChainTradeTransaction supplyChainTradeTransaction;
}
我还创建了一个名为namespacemapper的类,其中定义了XML中使用的不同命名空间
public class NamespaceMapper extends NamespacePrefixMapper {
public static final String QDT_PREFIX = "qdt"; // DEFAULT NAMESPACE
public static final String QDT_URI = "urn:un:unece:uncefact:data:standard:QualifiedDataType:100";
public static final String RAM_PREFIX = "ram"; // DEFAULT NAMESPACE
public static final String RAM_URI = "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100";
public static final String RSM_PREFIX = "rsm"; // DEFAULT NAMESPACE
public static final String RSM_URI = "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100";
public static final String UDT_PREFIX = "udt"; // DEFAULT NAMESPACE
public static final String UDT_URI = "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100";
public static final String XSI_PREFIX = "xsi"; // DEFAULT NAMESPACE
public static final String XSI_URI = "http://www.w3.org/2001/XMLSchema-instance";
@Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
if(QDT_PREFIX.equals(namespaceUri)) {
return QDT_PREFIX;
}
if(RAM_PREFIX.equals(namespaceUri)) {
return RAM_PREFIX;
}
if(RSM_PREFIX.equals(namespaceUri)) {
return RSM_PREFIX;
}
if(UDT_PREFIX.equals(namespaceUri)) {
return UDT_PREFIX;
}
if(XSI_PREFIX.equals(namespaceUri)) {
return XSI_PREFIX;
}
return suggestion;
}
@Override
public String[] getPreDeclaredNamespaceUris() {
return new String[] { QDT_URI, RAM_URI, RSM_URI, UDT_URI, XSI_URI };
}
}
,我还在应用程序中创建了一个package-info.java文件
@XmlSchema(
elementFormDefault= XmlNsForm.QUALIFIED,
namespace="http://www.example.com/FOO",
xmlns={
@XmlNs(
prefix="ns1",
namespaceURI="http://www.example.com/FOO"),
@XmlNs(
prefix="qdt",
namespaceURI="urn:un:unece:uncefact:data:standard:QualifiedDataType:100"),
@XmlNs(
prefix="ram",
namespaceURI="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"),
@XmlNs(
prefix="rsm",
namespaceURI="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"),
@XmlNs(
prefix="udt",
namespaceURI="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"),
@XmlNs(
prefix="xsi",
namespaceURI="http://www.w3.org/2001/XMLSchema-instance"),
}
)
package fr.dsidiff.app.ui.model.request.metadata;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
,我确实有一种将Java对象转换为XML字符串的方法。
private String payloadToXml(CrossIndustryInvoice invoice) throws JAXBException {
//Create JAXB Context
JAXBContext ctx = null;
try {
ctx = JAXBContext.newInstance(CrossIndustryInvoice.class);
Marshaller jaxbMarshaller = ctx.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter sw = new StringWriter();
jaxbMarshaller.marshal(invoice, sw);
return sw.toString();
} catch (JAXBException e) {
e.printStackTrace();
throw new JAXBException("Oops something went wrong");
}
}
我的问题是我生成的XML无效,名称空间不匹配。
这是我获得的XML样本:
<ns2:CrossIndustryInvoice xmlns="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:ns2="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:ns4="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:ns3="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
<ns2:ExchangedDocumentContext>
<BusinessProcessSpecifiedDocumentContextParameter>
<ID>A1</ID>
</BusinessProcessSpecifiedDocumentContextParameter>
<GuidelineSpecifiedDocumentContextParameter>
<ID>urn:factur-x.eu:1p0:basicwl</ID>
</GuidelineSpecifiedDocumentContextParameter>
</ns2:ExchangedDocumentContext>
虽然我应该得到一些不同的东西:
<?xml version='1.0' encoding='UTF-8'?>
<rsm:CrossIndustryInvoice xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100"
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<rsm:ExchangedDocumentContext>
<ram:BusinessProcessSpecifiedDocumentContextParameter>
<ram:ID>A1</ram:ID>
</ram:BusinessProcessSpecifiedDocumentContextParameter>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:factur-x.eu:1p0:basicwl</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
I have to build an XML file from a java object in a java maven project.
I have a class named CrossIndustryInvoice with XML annotations.
@Data
@Builder
@AllArgsConstructor @NoArgsConstructor
@XmlRootElement(name="CrossIndustryInvoice", namespace = NamespaceMapper.RSM_URI)
@XmlAccessorType(XmlAccessType.FIELD)
public
class CrossIndustryInvoice {
@XmlElement(name = "ExchangedDocumentContext", namespace = NamespaceMapper.RSM_URI)
private ExchangedDocumentContext exchangedDocumentContext;
@XmlElement(name = "ExchangedDocument", namespace = NamespaceMapper.RSM_URI)
private ExchangedDocument exchangedDocument;
@XmlElement(name = "SupplyChainTradeTransaction", namespace = NamespaceMapper.RSM_URI)
private SupplyChainTradeTransaction supplyChainTradeTransaction;
}
I also created a class named NamespaceMapper where i define the different namespaces used in my XML
public class NamespaceMapper extends NamespacePrefixMapper {
public static final String QDT_PREFIX = "qdt"; // DEFAULT NAMESPACE
public static final String QDT_URI = "urn:un:unece:uncefact:data:standard:QualifiedDataType:100";
public static final String RAM_PREFIX = "ram"; // DEFAULT NAMESPACE
public static final String RAM_URI = "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100";
public static final String RSM_PREFIX = "rsm"; // DEFAULT NAMESPACE
public static final String RSM_URI = "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100";
public static final String UDT_PREFIX = "udt"; // DEFAULT NAMESPACE
public static final String UDT_URI = "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100";
public static final String XSI_PREFIX = "xsi"; // DEFAULT NAMESPACE
public static final String XSI_URI = "http://www.w3.org/2001/XMLSchema-instance";
@Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
if(QDT_PREFIX.equals(namespaceUri)) {
return QDT_PREFIX;
}
if(RAM_PREFIX.equals(namespaceUri)) {
return RAM_PREFIX;
}
if(RSM_PREFIX.equals(namespaceUri)) {
return RSM_PREFIX;
}
if(UDT_PREFIX.equals(namespaceUri)) {
return UDT_PREFIX;
}
if(XSI_PREFIX.equals(namespaceUri)) {
return XSI_PREFIX;
}
return suggestion;
}
@Override
public String[] getPreDeclaredNamespaceUris() {
return new String[] { QDT_URI, RAM_URI, RSM_URI, UDT_URI, XSI_URI };
}
}
I also created a package-info.java file
@XmlSchema(
elementFormDefault= XmlNsForm.QUALIFIED,
namespace="http://www.example.com/FOO",
xmlns={
@XmlNs(
prefix="ns1",
namespaceURI="http://www.example.com/FOO"),
@XmlNs(
prefix="qdt",
namespaceURI="urn:un:unece:uncefact:data:standard:QualifiedDataType:100"),
@XmlNs(
prefix="ram",
namespaceURI="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"),
@XmlNs(
prefix="rsm",
namespaceURI="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"),
@XmlNs(
prefix="udt",
namespaceURI="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"),
@XmlNs(
prefix="xsi",
namespaceURI="http://www.w3.org/2001/XMLSchema-instance"),
}
)
package fr.dsidiff.app.ui.model.request.metadata;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
In my application, I do have a method that converts Java Object to XML String.
private String payloadToXml(CrossIndustryInvoice invoice) throws JAXBException {
//Create JAXB Context
JAXBContext ctx = null;
try {
ctx = JAXBContext.newInstance(CrossIndustryInvoice.class);
Marshaller jaxbMarshaller = ctx.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter sw = new StringWriter();
jaxbMarshaller.marshal(invoice, sw);
return sw.toString();
} catch (JAXBException e) {
e.printStackTrace();
throw new JAXBException("Oops something went wrong");
}
}
My problem is that the XML i generate is invalid and namespaces are not matching.
here is a sample of XML I obtain :
<ns2:CrossIndustryInvoice xmlns="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:ns2="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:ns4="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:ns3="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
<ns2:ExchangedDocumentContext>
<BusinessProcessSpecifiedDocumentContextParameter>
<ID>A1</ID>
</BusinessProcessSpecifiedDocumentContextParameter>
<GuidelineSpecifiedDocumentContextParameter>
<ID>urn:factur-x.eu:1p0:basicwl</ID>
</GuidelineSpecifiedDocumentContextParameter>
</ns2:ExchangedDocumentContext>
While i should get something different:
<?xml version='1.0' encoding='UTF-8'?>
<rsm:CrossIndustryInvoice xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100"
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<rsm:ExchangedDocumentContext>
<ram:BusinessProcessSpecifiedDocumentContextParameter>
<ram:ID>A1</ram:ID>
</ram:BusinessProcessSpecifiedDocumentContextParameter>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:factur-x.eu:1p0:basicwl</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我没有注意进口。在我的pom.xml中,我添加了以下依赖性:
在我的namespacemapper类中,我使用以下导入
导入com.sun.xml.bind.marshaller.namespaceprefixmapper;
i替换为:
导入com.sun.xml.internal.bind.marshaller.namespaceprefixmapper;
I didn't pay attention to the import. In my pom.xml I added the following dependency:
In my NamespaceMapper class I was using the following import
import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
I replaced it with :
import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;