Java:未在生成的XML中获得名称空间

发布于 2025-02-05 23:37:22 字数 6303 浏览 3 评论 0原文

我必须在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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

百合的盛世恋 2025-02-12 23:37:22

我没有注意进口。在我的pom.xml中,我添加了以下依赖性:

<!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl -->
<dependency>
  <groupId>com.sun.xml.bind</groupId>
  <artifactId>jaxb-impl</artifactId>
  <version>2.0.1</version>
</dependency>

在我的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:

<!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl -->
<dependency>
  <groupId>com.sun.xml.bind</groupId>
  <artifactId>jaxb-impl</artifactId>
  <version>2.0.1</version>
</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;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文