当前位置: 首页 > 知识库问答 >
问题:

Jaxb:在同一个包中解组具有多个命名空间的xml

濮阳景天
2023-03-14

我刚开始在xml中使用名称空间,所以我有点困惑,希望得到一些澄清。我有一个java服务,我正在接收具有许多不同名称空间的xml文档,当我开始工作时,我觉得我肯定做错了什么,所以我想检查一下。在我的包裹信息中。java我有我的模式注释,例如:

@javax.xml.bind.annotation.XmlSchema(
    xmlns={
        @javax.xml.bind.annotation.XmHS(prefix="train", namespaceURI="http://mycompany/train"), 
        @javax.xml.bind.annotation.XmHS(prefix="passenger", namespaceURI="http://mycompany/passenger")
    }, 
    elementFormDefault = javax.xml.bind.annotation.XmlNsForm=QUALIFIED
)

我有一辆火车.java在班级级别上注释如下:

@XmlRootElement(name="Train", namespace="http://mycompany/train")

并且类中的每个字段都注释为:

@XmlElement(name="Color") for example

列车包含乘客列表,因此有一个属性

private Set<Passenger> passengers;

并且该集合被注释为:

@XmlElementWrapper(name="Passengers")
@XmlElements(@XmlElement(name="Passenger", namespace="http://mycompany/passenger"))

然后在乘客体内。java类本身注释为:

@XmlElement(name="Passenger", namespace="http://mycompany/passenger")

最后,对于Passenger.java内部的个别字段,它们的注释如下:

@XmlElement(name="TicketNumber", namespace="http://mycompany/passenger")

所以当我有一个xml看起来像:

<train:Train>
   <train:Color>Red</train:Color>
   <train:Passengers>
       <train:Passenger>
           <passenger:TicketNumber>T101</passenger:TicketNumber>
       </train:Passenger>
   </train:Passengers>
</train:Train>

现在我解开了我收到的这个xml,并设置了Train的Color属性和Passenger的TicketNumber属性。但我不知道为什么我需要在TicketNumber上的XmlElement注释上添加命名空间url,但我不需要在Train上的Color属性上这样做。如果我从TicketNumber上的XmlElement注释中删除了namespace属性,那么xml中的值将不会映射到对象,除非我也从xml请求中删除了命名空间前缀。我觉得既然我已经为Passenger在XmlRootElement上定义了命名空间属性,我就不需要对类中的每个字段都这样做,就像我不必为Train那样,所以我假设我一定设置了错误。有人能告诉我正确的方向吗?谢谢

共有1个答案

蔚楷
2023-03-14

以下是基于您的模型的名称空间在JAXB(JSR-222)中如何工作的说明。

爪哇模型

程序包信息

以下是@XmlSchema注释的修改版本。它包含一些关键信息:

  • 命名空间-将用于限定未指定其他命名空间的全局元素(对应于@XmlRootElement@XmlElementDecl注释的元素(以及基于elementFormDefault值的本地元素)的默认命名空间。
  • 默认情况下,只有全局元素是命名空间限定的,但是通过将值设置为 XmlNsForm.QUALIFIED所有没有指定显式命名空间的元素都将使用 命名空间值限定。
  • xmlns是JAXB impl应该为这些命名空间使用的首选前缀集(尽管它们可能使用其他前缀)。
@XmlSchema(
    namespace="http://mycompany/train",
    elementFormDefault = XmlNsForm.QUALIFIED,
    xmlns={
       @XmlNs(prefix="train", namespaceURI="http://mycompany/train"), 
       @XmlNs(prefix="passenger", namespaceURI="http://mycompany/passenger")
   }
)
package forum15772478;

import javax.xml.bind.annotation.*;

火车

由于与 Train 类对应的所有元素都对应于@XmlSchema注释中指定的命名空间,因此我们不需要指定任何命名空间信息。

    < li >全局元素——< code > @ xmlroot element 批注对应于一个全局元素。 < li >本地元素——< code > @ XML element wrapper 和< code>@XmlElement批注对应于本地元素。
package forum15772478;

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement(name="Train")
public class Train {

    private List<Passenger> passengers;

    @XmlElementWrapper(name="Passengers")
    @XmlElement(name="Passenger")
    public List<Passenger> getPassengers() {
        return passengers;
    }

    public void setPassengers(List<Passenger> passengers) {
        this.passengers = passengers;
    }

}

乘客

如果与< code>Passenger类上的属性相对应的所有元素都将位于< code > http://my company/Passenger 命名空间中,则可以使用< code>@XmlType批注来覆盖< code>@XmlSchema批注中的< code >命名空间。

java prettyprint-override">package forum15772478;

import javax.xml.bind.annotation.*;

@XmlType(namespace="http://mycompany/passenger")
public class Passenger {

    private String ticketNumber;

    @XmlElement(name="TicketNumber")
    public String getTicketNumber() {
        return ticketNumber;
    }

    public void setTicketNumber(String ticketNumber) {
        this.ticketNumber = ticketNumber;
    }

}

或者,您可以在属性级别覆盖命名空间。

package forum15772478;

import javax.xml.bind.annotation.*;

public class Passenger {

    private String ticketNumber;

    @XmlElement(
        namespace="http://mycompany/passenger",
        name="TicketNumber")
    public String getTicketNumber() {
        return ticketNumber;
    }

    public void setTicketNumber(String ticketNumber) {
        this.ticketNumber = ticketNumber;
    }

}

演示代码

可以运行以下演示代码来证明一切正常:

演示

package forum15772478;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Train.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum15772478/input.xml");
        Train train = (Train) unmarshaller.unmarshal(xml);

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

}

输入.xml/输出

在下面的XML中,我添加了您的问题中XML文档中缺少的必要命名空间声明。

<train:Train 
   xmlns:train="http://mycompany/train" 
   xmlns:passenger="http://mycompany/passenger">
   <train:Color>Red</train:Color>
   <train:Passengers>
       <train:Passenger>
           <passenger:TicketNumber>T101</passenger:TicketNumber>
       </train:Passenger>
   </train:Passengers>
</train:Train>

了解更多信息

    < Li > http://blog . bdoughan . com/2010/08/JAXB-namespaces . html
 类似资料:
  • 我从 3 个不同的客户端收到 3 个不同的 xml 输入: 来自客户端1的输入1:(命名空间前缀:,命名空间url:) 来自客户端 2 的输入 2:(命名空间前缀:,命名空间 URL:) 从客户端3输入3:(名称空间前缀: 时,< li >调用< code>String.replace() 这让我想到这种变量命名空间的方法是否应该完全可以接受。如果有什么可以改进此代码的方法,那么我要求社区在答案/

  • 我使用SpringBoot创建了一个SOAP Web服务服务器,并且我能够成功创建一个endpoint。但是,我无法创建多个endpoint并使用不同的URL访问它们。我想通过URL来访问处理该过程。 每个endpoint接收到的SOAP消息具有相同的模式。(命名空间和localpart是相同的!!!)我不想公开WSDL。 例如。 userA向以下URL发送以下SOAP消息:http://soap

  • 我需要你在JAXB编组方面的帮助。这是关于命名空间的。我在这个令人惊叹的网站上阅读了不同的博客和很多答案,但我还没有意识到如何解决我的问题。 我需要用一些复杂的(至少对我来说)名称空间生成一个XML。 如您所见,该XML具有 < code > xmlns:xsi = " http://www . w3 . org/2001/XML schema-instance " 和 http://www.sa

  • 我有一个xml,我正在尝试解体。它失败,因为它缺少必需的命名空间。 需要成为: 这个NamespaceFilter的例子只处理一个名称空间。我需要一个将追加两个名称空间。

  • 问题内容: 我有一个这样的架构层次结构: 一个文件夹中的所有文件都具有相同的命名空间。 现在,我想将名称空间映射到特定的Java包(我不能更改名称空间)。 我找到了将架构绑定到程序包的解决方案。但是然后我必须为每个xsd文件创建一个条目: 有没有一种方法可以直接定义名称空间和程序包名称之间的绑定? 另一种方法是在maven中定义包: 但是然后我必须为每个文件夹创建一个执行,这并不是我真正想要的。

  • 我在名称空间方面有问题。我需要从一个公共api (Prestashop)解组。该api使用xml作为xlink类型,如下所示: 每种产品的 API 为: 我为每个XML生成了两个包含pojo类的包。我想从产品列表中获取给定id的任何产品的属性。 我有一个产品,其中包含@XMLSchema命名空间,但这个命名空间仅针对一个路径是静态的。我知道这不是这样做的方法。 下面,我的客户类。 这里有代码:ht