问题描述
我有一个应用程序使用Jaxb进行XML< - >转换,并使用maven-jaxb2-plugin自动生成类。
I have an application doing XML<->conversions using Jaxb and automatically generated classes with maven-jaxb2-plugin.
在我的架构深处,我有可能输入ANYxml。
Someplace deep in my schema, I have the possibility to enter "ANY" xml.
更新:这更好地描述了我的架构。一些已知的XML包含一个完全未知的部分(任何部分)。
Update: this better describes my schema. Some known XML wrapping a totally unknown part (the "any" part).
<xs:complexType name="MessageType">
<xs:sequence>
<xs:element name="XmlAnyPayload" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:any namespace="##any"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="OtherElements">
....
</xs:sequence>
此地图(由jaxb提供)这样的内部类。
This maps (by jaxb) to a inner class like this.
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"any"
})
public static class XmlAnyPayload {
@XmlAnyElement(lax = true)
protected Object any;
当我解组整个结构时,没问题。 Object any将呈现为org.apache.xerces.dom.ElementNSImpl。现在,我想手动重新创建Java对象,然后转到XML。我如何获取一些随机XML并放入any(org.apache.xerces.dom.ElementNSImpl)元素以构建Java对象?
When I unmarshall the entire structure, it is no problem. The "Object any" will render into a org.apache.xerces.dom.ElementNSImpl. Now, I want to recreate the Java object manually and then go to XML. How do I take some random XML and put into the any (org.apache.xerces.dom.ElementNSImpl) element to be able to build up the Java object?
,接下来的情况是当我把这个元素作为java时,我想解组这个部分(能够提取这个元素的XML字符串)。但这是不可能的。我得到一个关于根元素的例外。但是无法注释ElementNSImpl。
Also, the next case is when I have this element as java, I want to unmarshall this very part (to be able to extract the XML string of this element). But this is not possible. I get an exception about root elements. But it is not possible to annotate ElementNSImpl.
unable to marshal type "com.sun.org.apache.xerces.internal.dom.ElementNSImpl" as an element because it is missing an @XmlRootElement annotation
你有什么建议吗?如何处理这些问题?
Do you have any suggestions on how to handle these problems?
推荐答案
@XmlAnyElement(lax = true)
用简单的英语表示:
这正是发生的事情在你的情况下。因此,如果您想要实际解组此lax的内容,请为JAXB上下文提供您要解组的元素的映射。最简单的方法是使用 @XmlRootElement
This is exactly what is happening in your case. So if you want to actually unmarshal the content of this lax any, provide JAXB context with a mapping for the element you wish to unmarshal. The easiest way to do this is to annotate your class with @XmlRootElement
@XmlRootElement(name="foo", namespace="urn:bar")
public class MyClass { ... }
现在,当您创建JAXB上下文时,将 MyClass
添加到其中:
Now when you create your JAXB context, add MyClass
into it:
JAXBContext context = JAXBContext.newInstance(A.class, B.class, ..., MyClass.class);
在这种情况下,如果JAXB符合 {urn:bar} foo
元素代替 xs:any
,它会知道这个元素被映射到 MyClass
并尝试解组MyClass。
In this case, if JAXB meets the {urn:bar}foo
element in the place of that xs:any
, it will know that this element is mapped onto MyClass
and will try to unmarshal MyClass.
如果你是根据包名创建JAXB上下文(你可能会这样做),你仍然可以添加你的类(比方说, com.acme.foo.MyClass
)。最简单的方法是创建 com / acme / foo / jaxb.index
资源:
If you are creating JAXB context based on the package name (you probably do), you can still add you class (say, com.acme.foo.MyClass
) to it. The easiest way is to create a com/acme/foo/jaxb.index
resource:
com.acme.foo.MyClass
并将包名添加到上下文中路径:
And the add your package name to the context path:
JAXBContext context = JAXBContext.newInstance("org.dar.gee.schema:com.acme.foo");
还有其他方法可以使用 ObjectFactory
等。 ,但是 jaxb.index
的技巧可能是最简单的。
There are other ways with ObjectFactory
etc., but the trick with jaxb.index
is probably the easiest one.
或者,不要在一个中解组所有内容运行时,您可以将 xs:any
的内容保留为DOM,并在第二次解组时将其解组到目标对象中,并使用其他JAXB上下文(知道您的 MyClass 类)。类似于:
Alternatively, instead of unmarshalling everything in one run, you can leave the content of xs:any
as DOM and unmarshal it into the target object in a second unmarshalling with anothe JAXB context (which know your MyClass
class). Something like:
JAXBContext payloadContext = JAXBContext.newInstance(MyClass.class);
payloadContext.createUnmarshaller().unmarshal((Node) myPayload.getAny());
这种方法有时更好,特别是当你有相对独立的容器/有效载荷模式的组合时。取决于案例。
This approach is sometimes better, especially when you have a combination of container/payload schemas which are relatively independent. Depends on the case.
上述所有内容也适用于编组。它完全是双向的。
All said above applies to marshalling as well. It's all neatly bidirectional.
这篇关于Jaxb:如何解组xs:任何XML字符串部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!