JAXB:为啥在生成的 xml 文档中未使用定义的命名空间前缀?

Posted

技术标签:

【中文标题】JAXB:为啥在生成的 xml 文档中未使用定义的命名空间前缀?【英文标题】:JAXB: why are defined namespace prefixes not used in generated xml document?JAXB:为什么在生成的 xml 文档中未使用定义的命名空间前缀? 【发布时间】:2021-04-03 09:12:33 【问题描述】:

您好,我使用 xic 编译器从 xml 模式文件 (mets.xsd) java 类生成。此 xsd 文件使用一些其他名称空间(premis.xsd、ead.xsd ...)。为了使用命名空间前缀,我在 package-info.java 文件中添加了一些注释,如下所示:

@XmlSchema(
    elementFormDefault=XmlNsForm.QUALIFIED,
    location="http://www.loc.gov/mets/mets.xsd",
    namespace="http://www.loc.gov/METS/",
    xmlns=
    
            @XmlNs(prefix="METS",   namespaceURI="http://www.loc.gov/mets/"),
            @XmlNs(prefix="EAD",    namespaceURI="http://www.loc.gov/ead/"),
            @XmlNs(prefix="PREMIS", namespaceURI="http://www.loc.gov/premis/v2/"),
            @XmlNs(prefix="xlink",  namespaceURI="http://www.w3.org/1999/xlink"),
            @XmlNs(prefix="OAI_DC", namespaceURI="http://www.openarchives.org/OAI/2.0/oai_dc/"),
            @XmlNs(prefix="DC",     namespaceURI="http://purl.org/dc/elements/1.1/")
    
)
package ch.eugster.herakles.sip.matterhorn.mets;

import jakarta.xml.bind.annotation.XmlNs;
import jakarta.xml.bind.annotation.XmlNsForm;
import jakarta.xml.bind.annotation.XmlSchema;

当我将 java 对象编组为 xml 时,我得到以下输出:

<?xml version="1.0" encoding="UTF-8"?>
<ns1:mets xmlns:METS="http://www.loc.gov/mets/" xmlns:EAD="http://www.loc.gov/ead/" xmlns:PREMIS="http://www.loc.gov/premis/v2/" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:OAI_DC="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:DC="http://purl.org/dc/elements/1.1/" xmlns:ns1="http://www.loc.gov/METS/" PROFILE="http://www.docuteam.ch/xmlns/sip-profile.xml">
   <ns1:amdSec/>
   <ns1:fileSec>
      <ns1:fileGrp/>
   </ns1:fileSec>
   <ns1:structMap>
      <ns1:div TYPE="rootfolder" ORDER="1" LABEL="RootFolder_Temp"/>
   </ns1:structMap>
</ns1:mets>

如您所见,前缀定义正确,但未在文档中使用。有谁知道,这可能是什么原因?非常感谢!

【问题讨论】:

嗨,即使我实际上也面临同样的问题。在创建QName 期间不使用提供的prefix。它总是使用默认的命名空间前缀,例如ns0,ns1, etc。我也在使用Moxy。你找到这个问题的答案了吗? 【参考方案1】:

即使我也面临同样的问题(即使在将custom prefix 提供给我的QName 之后,我也得到了默认的命名空间前缀,例如ns0,ns1,etc)所以我尝试了很多东西,终于能够得到它所以在这里发布相同的内容,以便对您以及将来的其他人有所帮助。你可以找到my question here

    删除package-info.java 及其所有内容(如果您在尝试某些内容时添加了)。

    由于您使用的是Moxy,因此您可以使用所有必需的NamespcaeURI and Prefix 创建一个Map。像这样的:

Map<String, String> urisToPrefixes = new HashMap<String, String>();
urisToPrefixes.put("http://www.loc.gov/mets/", "METS");
urisToPrefixes.put("http://www.loc.gov/ead/", "EAD"); 
urisToPrefixes.put("http://www.loc.gov/premis/v2/", "PREMIS"); 
    使用Marshalling 方法时,添加property 并将此Map 作为参数发送:
    marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, urisToPrefixes);

这将确保无论何时遇到Namespace,它都会检查相应的prefix并将其添加到XML header,因此它将所有默认前缀ns0,ns1 etc替换为对应的prefix从地图上看。

完整的示例代码:

JAXBContext ctx = JAXBContext.newInstance(new Class[]  TestObject.class, SubObject.class );
Map<String, String> urisToPrefixes = new HashMap<String, String>();
urisToPrefixes.put("http://www.loc.gov/mets/", "METS");
urisToPrefixes.put("http://www.loc.gov/ead/", "EAD"); urisToPrefixes.put("http://www.loc.gov/premis/v2/", "PREMIS");
Marshaller m = ctx.createMarshaller();
m.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, prefixesToUris);

如果您想了解更多关于此和其他方法的信息,请查找documentation here:

【讨论】:

以上是关于JAXB:为啥在生成的 xml 文档中未使用定义的命名空间前缀?的主要内容,如果未能解决你的问题,请参考以下文章

使用 JAXB 将 XML 文档嵌入到另一个 XML 中

java生成解析xml的另外两种方法JAXB

java生成解析xml的另外两种方法JAXB

如何在IJ中使用Jaxb2通过xml定义生成对应的Java Entity类的文件

JAXB使用方式

如何仅从 XML 生成 JAXB 类