当前位置: 首页 > 面试题库 >

Jaxb:如何解组XS:任何XML字符串部分?

仲孙温文
2023-03-14
问题内容

我有一个使用Jaxb进行XML <->转换的应用程序,并使用maven-jaxb2-plugin自动生成了类。

在我模式的某个深处,我可以输入“ ANY” xml

更新:这更好地描述了我的架构。一些已知的XML包装了一个完全未知的部分(“ any”部分)。

<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)映射到这样的内部类

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "any"
})
public static class XmlAnyPayload {

    @XmlAnyElement(lax = true)
    protected Object any;

当我解组整个结构时,这没问题。“任何对象”将呈现到org.apache.xerces.dom.ElementNSImpl中。现在,我想手动重新创建Java对象,然后转到XML。如何获取一些随机XML并将其放入any(org.apache.xerces.dom.ElementNSImpl)元素中,以便能够构建Java对象?

另外,下一种情况是当我将此元素作为java时,我想解组这部分内容(以便能够提取此元素的XML字符串)。但这是不可能的。我对根元素有一个例外。但是无法注释ElementNSImpl。

unable to marshal type "com.sun.org.apache.xerces.internal.dom.ElementNSImpl" as an element because it is missing an @XmlRootElement annotation

您对如何处理这些问题有任何建议吗?


问题答案:

@XmlAnyElement(lax = true) 用简单的英语意思是:

亲爱的JAXB!如果您有此元素的映射,请将其解组为Java对象。如果您不知道此元素,请将其保留为DOM元素。

这正是您的情况。因此,如果您想实际解组此松散内容的内容,请为JAXB上下文提供要解组的元素的映射。最简单的方法是用@XmlRootElement

@XmlRootElement(name="foo", namespace="urn:bar")
public class MyClass { ... }

现在,当您创建JAXB上下文时,添加MyClass到其中:

JAXBContext context = JAXBContext.newInstance(A.class, B.class, ..., MyClass.class);

在这种情况下,如果JAXB
{urn:bar}foo在那个位置遇到元素xs:any,它将知道该元素已映射到该元素MyClass,并尝试解组MyClass。

如果要基于包名称创建JAXB上下文(您可能会这样做),则仍可以向其中添加类(例如com.acme.foo.MyClass)。最简单的方法是创建com/acme/foo/jaxb.index资源:

com.acme.foo.MyClass

并将您的包名称添加到上下文路径:

JAXBContext context = JAXBContext.newInstance("org.dar.gee.schema:com.acme.foo");

等还有其他方法ObjectFactory,但是窍门jaxb.index可能是最简单的方法。

另外,您也可以将xs:anyas DOM
的内容保留为DOM,然后通过JAXB上下文(知道您的MyClass类)进行第二次解组,而不用一次将所有内容解组。就像是:

JAXBContext payloadContext = JAXBContext.newInstance(MyClass.class);
payloadContext.createUnmarshaller().unmarshal((Node) myPayload.getAny());

这种方法有时会更好,特别是当您具有相对独立的容器/有效负载方案组合时。视情况而定。

上述所有内容也适用于编组。全部都是双向的。



 类似资料:
  • 问题解决 将XmlElementRef注释更改为@XmlElementRef(name=“Option”,type=Option.class,required=false)后,将@XmlRootElement(name=“Option”)添加到选项中。班 更新: 根据laune的建议,我添加了两个类(Options和Option),并修改了GuimopProperties类,如下所示 但当我必须新

  • 当我使用JAXB时,出现了一些问题。 我将实体转换为xml字符串,一切正常。 但当我将xml字符串转换回实体时,一些信息丢失了(它们都具有相同的类型)。 在实体中:

  • 我需要使用Jackson解析字符串数组(标识符)。我在互联网上没有找到任何例子,所有的例子都展示了如何反序列化某个类的对象数组,但我只需要解析一个字符串数组(不需要为它编写模型类),我该怎么做呢?JSON示例:

  • 我有一个XML字符串,如下所示: 现在,我用名称数据将其解组到类中。java,它将变量作为CustomerInfo的另一个类。JAVA 但在解组时,我得到了一个错误作为意外元素(uri:)https://www.google/com,本地:“数据”)。预期的元素为

  • 错误中的SOAP WSDL URL是Spring Boot应用程序中的另一个web服务。试图理解为什么这会出现在错误中。 UnmarshalException:意外元素(URI:“”,local:“message”)。需要的元素是<{http://soap_wsdl_url}jaxb_pojo_name>

  • 问题内容: 我通过通过PHP回显将XML文档发送给AJAX调用来进行响应。为了形成这个XML文档,我遍历了数据库的记录。问题在于数据库中包含带有’<’符号的记录。因此,浏览器自然会在该特定位置引发错误。如何解决? 问题答案: 通过使用(或可能更适当地)使用库来构建XML文档(例如DOMDocument或XMLWriter)来转义这些字符。 另一种替代方法是使用CDATA节,但是您必须注意是否出现。