【问题标题】:JAXB - marshall (uppercase, lowercase, namespaces, ns2)JAXB - 编组(大写、小写、命名空间、ns2)
【发布时间】:2018-02-14 13:56:27
【问题描述】:

我通过 xjc 从一个大 XSD 文件生成了大约 100 个(如果不是更多)Java 类。

该 XSD 文件的元素具有大写名称。现在,当我从这些生成的 Java 类中编组一个对象时,我遇到了一些问题。

JAXB marshall 生成的示例 XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<advertiser xmlns:ns2="http://p.t.com/service">
    <ns2:Name>TEST Adv 001</ns2:Name>
</advertiser>
  1. 元素的名称(但不是子元素的名称)由 JAXB 以小写形式生成。我需要它们是大写的(因为它们在 XSD 中)。

  2. 有一些奇怪的 ns2: 元素名称的前缀,例如 我希望此示例中的 xmlns:ns2 仅变为 xmlns,而 ns2:Name 仅变为 Name。 SO上的一个答案建议将attributeFormDefault="unqualified"放在XSD中,但似乎也没有帮助我。

如何解决这两个问题?

我在这里寻找类似的问题,但没有找到与我完全相同的问题。此外,那里的答案看起来很复杂,他们要求更改我无法做到的 Java 类。为什么要这么复杂?!

请注意,我的 Java 类是自动生成的,所以我不想手动更改它们。

我想知道为什么 XSD 说的是一件事,而 JAXB 编组进程产生的是另一件事。 JAXB marshall 不应该生成 100% 符合 XSD 的 XML 吗?

编辑

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Advertiser", propOrder = {

})
public class Advertiser {

    @XmlElement(name = "TelID")
    protected Integer telID;

    @XmlElement(name = "Name")
    protected String name;

    @XmlElementRef(name = "Address", namespace = "http://p.t.com/service", type = JAXBElement.class)
    protected JAXBElement<String> address;

.............

编辑 2

    Advertiser adv = new Advertiser();
    adv.setName("TEST Adv 001");

    StringWriter sw = new StringWriter();
    JAXB.marshal(adv, sw);
    System.out.println(sw.toString());

【问题讨论】:

    标签: java jaxb


    【解决方案1】:

    1) 奇怪。由于您已经从 XSD 生成了类,因此它们应该有足够的注释,如果 XSD 中的元素是大写的,您应该得到带有大写元素名称的 @XmlElement 注释。发布几个模式派生类,有趣的是它们的样子。您是对的,当您从 XSD 生成类时,您应该在编组时获得符合 XSD 的 XML(或多或少)。至少元素的大小写应该匹配。这很奇怪,我无法解释。发布您的课程,我们会看到。

    2) 见

    Is it possible to customize the namespace prefix that JAXB uses when marshalling to a String?

    更新。

    好的,现在我知道问题出在哪里了。你编组了一个Advertiser 的实例,但它只是一个@XmlType 而不是@XmlRootElement。所以 JAXB 不知道应该在哪个根元素中编组它,并且默认情况下会在空命名空间中生成 advertiser,小写字母。

    要解决此问题,您可以添加 @XmlRootElement 注释或将您的 Advertiser 实例包装到 JAXBElement 中。

    对于后者,请检查与 Advertiser 类在同一包中的 ObjectFactory 类。你可以这样做(类似):

    ObjectFactory objectFactory = new ObjectFactory();
    JAXBElement<Advertiser> advElement = objectFactory.createAdvertiser(adv);
    

    编组advElement 应该为您提供正确的元素名称。

    在编译 XML Schemas 时,XJC 会为每个全局元素生成这样的createXYZ(XYZ value) 方法。

    【讨论】:

    • 感谢您的帮助。我添加了 Advertiser 类的启动方式。
    • 我只是将 elementFormDefault="unqualified" 放在 XSD 中,然后在没有 ns2 的情况下生成了子元素的名称。因此,在我发布的示例中,我得到了 而不是 .
    • Name 元素按照注释指定的方式编组,以大写字母开头。我不太确定大写的问题是什么,需要详细说明吗?
    • elementFormDefault="unqualified" - 好吧,这有效地从子元素中删除了命名空间。我认为这不是你想要的。
    • 嗯...但是 elementFormDefault="qualified" 的存在不是什么让这个 ns2 出现在子元素中吗?
    猜你喜欢
    • 2023-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-04
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多