【问题标题】:JAXB marshalling vs. XSD schema generation - "desynchronize" itJAXB 编组与 XSD 模式生成 - “去同步”它
【发布时间】:2012-12-12 15:57:32
【问题描述】:

对于给定的类结构(跳过注释等):

class A {
 public B getObjectB {}
}

class B {
 public String getHello { return " world"; }
}

生成正确的 XSD 和 XML 输出没有问题:

<A>
 <B>
  <hello>world</hello>
 </B>
</A>

问题是,我需要稍微打破它:首先,XSD 应该保持原样 - 已满。但是在编组 A 时,我需要得到这样的东西:

<A>
 someStringForA
</A>

(因此 B 呈现为一些计算的字符串)。同时,在编组 B(作为根)时,我仍然需要获得“正常”输出。

我尝试使用 XmlAdapters,但使用 @XmlJavaTypeAdapter 也会更改 XSD。通过 Marshaller.setAdapter(...) 设置适配器显然(http://stackoverflow.com/questions/6110757/jaxb-xml-adapters-work-via-annotations-but-not-via-setadapter/6112149#6112149)不行。

如果有可能“关闭”@XmlJavaTypeAdapter(XSD 由 JUnit“手动”生成,允许进行一些切换甚至 hack),则某种解决方案是

感谢您的帮助!

【问题讨论】:

    标签: java jaxb xml-serialization


    【解决方案1】:

    注意:我是 EclipseLink JAXB (MOXy) 负责人,也是JAXB (JSR-222) 专家组的成员。

    备用映射 - oxm.xml

    如果您使用 MOXy 作为您的 JAXB 提供程序,您可以使用外部映射文件为您的域模型提供备用映射(请参阅:http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html)。

    <?xml version="1.0"?>
    <xml-bindings
        xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
        package-name="forum13843624">
        <java-types>
            <java-type name="A">
                <java-attributes>
                    <xml-value java-attribute="objectB"/>
                </java-attributes>
            </java-type>
            <java-type name="B">
                <java-attributes>
                    <xml-value java-attribute="hello"/>
                </java-attributes>
            </java-type>
        </java-types>
    </xml-bindings>
    

    Java 模型

    一个

    import javax.xml.bind.annotation.*;
    
    @XmlRootElement(name="A")
    class A {
    
        private B b;
    
        @XmlElement(name="B")
        public B getObjectB() {
            return b;
        }
        public void setObjectB(B b) {
            this.b = b;
        }
    
    }
    

    B

    import javax.xml.bind.annotation.XmlElement;
    
    class B {
    
        @XmlElement
        public String getHello() {
            return " world";
        }
    
    }
    

    jaxb.properties

    要将 MOXy 指定为您的 JAXB 提供程序,您需要在与域模型相同的包中包含一个名为 jaxb.properties 的文件,并使用以下条目(请参阅:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html)。

    javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
    

    演示代码

    import java.util.*;
    import javax.xml.bind.*;
    import org.eclipse.persistence.jaxb.JAXBContextProperties;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            B b = new B();
            A a = new A();
            a.setObjectB(b);
    
            JAXBContext jc = JAXBContext.newInstance(A.class);
            marshal(jc, a);
    
            Map<String, Object> properties = new HashMap<String, Object>();
            properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum13843624/oxm.xml");
            JAXBContext jc2 = JAXBContext.newInstance(new Class[] {A.class}, properties);
            marshal(jc2, a);
        }
    
        private static void marshal(JAXBContext jc, A a) throws Exception {
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(a, System.out);
        }
    
    }
    

    输出

    下面是运行演示代码的输出。注意同一个对象图是如何以两种不同的方式编组的。

    <?xml version="1.0" encoding="UTF-8"?>
    <A>
       <B>
          <hello> world</hello>
       </B>
    </A>
    <?xml version="1.0" encoding="UTF-8"?>
    <A> world</A>
    

    【讨论】:

    • 感谢 Blaise 的出色回答 - 我希望有人为此付出代价 ;) 我看到了您以前的回答和帖子,并正在考虑切换到 MOXy,但希望没有必要...我会检查后果
    • @Tomasz - 我不确定你的用例是否 100% 正确。你真的想像我在回答中那样将 A 编组为多个 XML 表示吗?
    • 是的。或者更确切地说 - 我需要将它的一些子元素(B)编组为一些字符串(实际上是 URL)。同时,在将 B 编组为 root 时,不应将其转换为该字符串(URL)——它应该是“正常”的 XML 输出(除非有一些 C 嵌套,并且配置为类似于 B)。如果您想知道原因,这一切都与“边缘包含”有关;)
    猜你喜欢
    • 2023-02-10
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 1970-01-01
    • 2012-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多