jaxb 命名空间提供了不需要的 ns2 前缀

jaxb namespace gives unneeded ns2 prefix

我需要在 xml 中生成命名空间,但这会导致我不需要的不一致的 ns2 前缀(我没有混合命名空间)。我尝试了几种我没有找到的解决方案。

包-info.java

    @javax.xml.bind.annotation.XmlSchema(namespace="http://namespace" ,
        elementFormDefault=javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
        xmlns={
        @javax.xml.bind.annotation.XmlNs(namespaceURI="http://namespace", prefix="")
        })

    package hu.xml.create;

POJO

    @XmlRootElement(name = "create", namespace = "http://namespace")
    public class Create{
    ...

编组器

    public String mashal(Object object) throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(object.getClass());
        Marshaller mar= context.createMarshaller();
        mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    
        StringWriter sw = new StringWriter();

        mar.marshal(object, sw);

        return sw.toString();
}

通话

    @RequestMapping("/export/{id}")
    public String export(Model model, @PathVariable(value = "id") Long id) {
        String method = "export";
    
        Create create = new Create(...);
        try {
            String xml = RequestHandler.getInstance().mashal(create);
            model.addAttribute("xml", xml);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    
        return "export";
}

结果

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ns2:create xmlns:ns2="http://namespace">
        <ns2:tag>
            <subtag>true</subtag>

需要命名空间前缀,因为您有像 <subtag> 这样没有命名空间的元素。为它们分配命名空间后,ns2 前缀将消失,JAXB 将根据需要使用默认命名空间。

在 JAXB RI 的 NamespaceContextImpl#declareNsUri 中也有一条评论指出:

// the default prefix is already taken.
// move that URI to another prefix, then assign "" to the default prefix.

编辑: 如果您无法去除不合格的元素,您可以使用与其他元素相同的命名空间来限定它们。这至少对于 JAXB RI 是可能的,并且等效于 <xsd:include> 标记:

final Map<String, String> props = Collections.singletonMap(JAXBRIContext.DEFAULT_NAMESPACE_REMAP, "http://namespace");
final JAXBContext ctx = JAXBContext.newInstance(new Class[]{Create.class}, props);