如何修复 Jackson 为同一名称空间渲染多个名称空间前缀

Ken*_*enB 7 java xml xml-serialization xml-namespaces jackson-dataformat-xml

我有一个 pojo,我正在使用 com.fasterxml.jackson.dataformat.xml.XmlMapper 序列化它。

我有一个用多个字符串值定义的 Java 类。

@JacksonXmlRootElement(namespace = "http://www.firstnamespace.com", localName = "Student")    
public class Student {
    @JacksonXmlProperty(namespace = "http://www.firstnamespace.com",localName = "ID")
    public final String id;
    @JacksonXmlProperty(namespace = "http://www.firstnamespace.com",localName = "Name")
    public final String name;
    @JacksonXmlProperty(namespace = "http://www.firstnamespace.com",localName = "Address")
    public Address address;
}
Run Code Online (Sandbox Code Playgroud)

地址定义如下,地址的元素位于不同的命名空间中

public class Address {
    @JacksonXmlProperty(namespace = "http://www.secondnamespace.com",localName = "StreetNumber")
    public final String streetNumber;
    @JacksonXmlProperty(namespace = "http://www.secondnamespace.com",localName = "StreetName")
    public final String steetName;
}
Run Code Online (Sandbox Code Playgroud)

当我用 Jackson 序列化 Student 时,我最终得到了地址对象的一堆重复的命名空间。

<Student xmlns="http://www.firstnamespace.com">
    <ID>1234</ID>
    <Name>Ken</Name>
    <Address>
        <wstxns1:StreetNumber xmlns:wstnxs1="http://www.secondnamespace.com">Ken</wstxns1:StreetNumber>
        <wstxns2:StreetName xmlns:wstnxs2="http://www.secondnamespace.com">Main Street</wstxns2:StreetName>
    </Address>
Run Code Online (Sandbox Code Playgroud)

我正在像这样序列化 Student 类:

XmlMapper xmlMapper = new XmlMapper();
xmlMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
xmlMapper.writeValue(new File("studentTest.xml", student);
File file = new File("studentTest.xml");
Run Code Online (Sandbox Code Playgroud)

有没有办法为给定的命名空间创建单个命名空间前缀?

<Student xmlns="http://www.firstnamespace.com">
    <ID>1234</ID>
    <Name>Ken</Name>
    <Address>
        <wstxns1:StreetNumber xmlns:wstnxs1="http://www.secondnamespace.com">Ken</wstxns1:StreetNumber>
        <wstxns1:StreetName>Main Street</wstxns1:StreetName>
    </Address>
Run Code Online (Sandbox Code Playgroud)

或者在顶部定义名称空间?

<Student xmlns="http://www.firstnamespace.com" xmlns:wstnxs1="http://www.secondnamespace.com">
    <ID>1234</ID>
    <Name>Ken</Name>
    <Address>
        <wstxns1:StreetNumber>Ken</wstxns1:StreetNumber>
        <wstxns1:StreetName>Main Street</wstxns1:StreetName>
    </Address>
Run Code Online (Sandbox Code Playgroud)

我读到我需要使用 Woodstox 来帮助解决这个问题,并且我尝试了以下方法,但我不知道 Woodstox 配置如何帮助解决这个问题。但是我可以更改前缀:

XMLInputFactory2  inputFactory2 =  new WstxInputFactory();
XMLOutputFactory2 outputFactory2 = new WstxOutputFactory();

outputFactory2.setProperty(XMLOutputFactory2.P_AUTOMATIC_NS_PREFIX,"foo");
outputFactory2.configureForRobustness();
XmlFactory xmlFactory = new XmlFactory(inputFactory2,outputFactory2);
XmlMapper xmlMapper = new XmlMapper(xmlFactory);
Run Code Online (Sandbox Code Playgroud)