是否可以自定义JAXB在编组到String时使用的名称空间前缀?

25 java-metro-framework jaxb xml-serialization jaxb2

例如,我有一个导入另一个模式的简单模式.第二个模式(urn:just:attributes,just-attributes.xsd)只定义了一个属性组.

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org/MySchema"
    xmlns:tns="http://www.example.org/MySchema" 
    elementFormDefault="qualified"
    xmlns:ja="urn:just:attributes">

    <import schemaLocation="just-attributes.xsd" namespace="urn:just:attributes"/>

    <element name="MyElement">
        <complexType>
            <attributeGroup ref="ja:AttributeGroup"/>
        </complexType>
    </element>
</schema>
Run Code Online (Sandbox Code Playgroud)

我正在使用Metro xjc Ant任务来生成此模式的类.我遇到的问题是我正在与之交互的第三方应用程序是名称空间特有的.这种情况我需要一个String值,所以我必须序列化它.我使用样板代码.

private static <T> String marshal(T object) throws JAXBException{
    OutputStream outputStream = new ByteArrayOutputStream();
    JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());
    Marshaller marshaller = jaxbContext.createMarshaller();
    marshaller.marshal(object, outputStream);
    return outputStream.toString();
}
Run Code Online (Sandbox Code Playgroud)

这给了我一些东西

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:MyElement xmlns:ns1="urn:just:attributes" xmlns:ns2="http://www.example.org/MySchema" ns1:attrib1="1234" ns1:attrib2="5678"/>
Run Code Online (Sandbox Code Playgroud)

xmlns:thirdpartyns="urn:just:attributes"遇到的问题是这个第三方需要类似的东西,也就是说,它们是根据命名空间的名称进行解析.它已经是"thirdpartyns"为他们的软件工作.

有没有人知道如何解决这个问题,而不是在结果字符串中进行查找和替换?也许是自定义绑定规则?

Dav*_*veC 27

http://hwellmann.blogspot.com/2011/03/jaxb-marshalling-with-custom-namespace.html

这显示了如何做到这一点.

另一个:http://www.systemmobile.com/? p = 280

链路死亡时的关键位:

NamespacePrefixMapper类,位于com.sun.xml.bind.marshaller包中.抽象类有一个实现方法:

public abstract String getPreferredPrefix(  
     String namespaceUri,         
     String suggestion,         
     boolean requirePrefix); 
Run Code Online (Sandbox Code Playgroud)

然后

Marshaller marshaller =        
    jaxbContext.createMarshaller();        
marshaller.setProperty(”com.sun.xml.bind.namespacePrefixMapper”,        
    new MyNamespacePrefixMapper());  
Run Code Online (Sandbox Code Playgroud)

如果您还使用javax.xml.xpath.XPath,则NamespacePrefixMapper还可以实现javax.xml.namespace.NamespaceContext,将命名空间自定义集中在一个类中.


bas*_*ero 11

我在Java SE6中对它进行了测试,与Java SE 5的解决方案(如上所述)相比,它需要进行一些小改动:

    Marshaller m = context.createMarshaller();
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
    m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
    m.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", mapper);
Run Code Online (Sandbox Code Playgroud)

因此.internal.,与Java SE5版本相比,上面的第三个属性包含包名称中的附加内容.我还没有发现的是如何告诉Marshaller哪个名称空间URI成为默认名称空间("").如果我重写方法getPreferredPrefix()并返回一个空字符串,Marshaller在编写默认命名空间的属性方面存在问题(在这种情况下,它会创建一个名为ns1的新命名空间)

  • 显然在java SE 7中,它再次使用"com.sun.xml.bind.namespacePrefixMapper"....(使用Java SE 6属性我得到一个例外) (2认同)
  • 有人知道Java SE 8的正确性吗?@edbras (2认同)

Wes*_*lor 6

我有同样的问题.在package-info.java(如果你没有它,你可以手动创建它)添加xmlns部分:

@javax.xml.bind.annotation.XmlSchema(xmlns = {
        @javax.xml.bind.annotation.XmlNs(namespaceURI = "urn:just:attributes", prefix = "thirdpartyns") }, 
        elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
Run Code Online (Sandbox Code Playgroud)

  • 如果我从xsd生成源怎么办?使用apache插件maven。如何以这种方式自定义? (2认同)