注意: 我是 Eclipselink
JAXB(MOXy)的 负责人,并且是
JAXB(JSR-222) 专家组的成员。
使用
@XmlAnyElement注解并指定来映射此用例
DOMHandler。使用JAXB
RI执行此操作时似乎出现了错误,但是以下用例适用于Eclipselink JAXB(MOXy)。
BodyDomHandler
默认情况下,JAXB实现将未映射的内容表示为DOM节点。您可以利用
DomHandler来表示DOM的替代表示,在这种情况下,我们将DOM表示为
String。
import java.io.*;import javax.xml.bind.ValidationEventHandler;import javax.xml.bind.annotation.DomHandler;import javax.xml.transform.Source;import javax.xml.transform.stream.*;public class BodyDomHandler implements DomHandler<String, StreamResult> { private static final String BODY_START_TAG = "<body>"; private static final String BODY_END_TAG = "</body>"; private StringWriter xmlWriter = new StringWriter(); public StreamResult createUnmarshaller(ValidationEventHandler errorHandler) { return new StreamResult(xmlWriter); } public String getElement(StreamResult rt) { String xml = rt.getWriter().toString(); int beginIndex = xml.indexOf(BODY_START_TAG) + BODY_START_TAG.length(); int endIndex = xml.indexOf(BODY_END_TAG); return xml.substring(beginIndex, endIndex); } public Source marshal(String n, ValidationEventHandler errorHandler) { try { String xml = BODY_START_TAG + n.trim() + BODY_END_TAG; StringReader xmlReader = new StringReader(xml); return new StreamSource(xmlReader); } catch(Exception e) { throw new RuntimeException(e); } }}信息
下面是
@XmlAnyElement在
Message类上指定注释的方式。
import javax.xml.bind.annotation.XmlAnyElement;import javax.xml.bind.annotation.XmlType;@XmlType(propOrder = { "body" })public class Message{ private String body; public String getBody() { return body; } @XmlAnyElement(BodyDomHandler.class) public void setBody(String body) { this.body = body; }}输出量
以下是运行your的输出
SerialziationTest:
<?xml version="1.0" encoding="UTF-8"?><Report> <message> <body>Sample report message.</body> </message></Report><?xml version="1.0" encoding="UTF-8"?><Report> <message> <body> <rootTag> <body>All systems online.</body> </rootTag> </body> </message></Report>
想要查询更多的信息
- http://blog.bdoughan.com/2011/04/xmlanyelement-and-non-dom-properties.html
- http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
注意-JAXB RI中的错误
JAXB参考实现中似乎存在一个错误,示例代码将导致如下所示的堆栈跟踪:
Exception in thread "main" javax.xml.bind.MarshalException - with linked exception:[com.sun.istack.internal.SAXException2: unable to marshal type "java.lang.String" as an element because it is missing an @XmlRootElement annotation] at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:317) at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:243) at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:75) at forum12428727.SerializationTest.main(SerializationTest.java:20)Caused by: com.sun.istack.internal.SAXException2: unable to marshal type "java.lang.String" as an element because it is missing an @XmlRootElement annotation at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:216) at com.sun.xml.internal.bind.v2.runtime.LeafBeanInfoImpl.serializeRoot(LeafBeanInfoImpl.java:126) at com.sun.xml.internal.bind.v2.runtime.property.SingleReferenceNodeProperty.serializeBody(SingleReferenceNodeProperty.java:100) at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:306) at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:664) at com.sun.xml.internal.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:141) at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:306) at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:561) at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:290) at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:462) at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:314) ... 3 more



