首页 > 解决方案 > 将 xPath 节点绑定到 java Bean 对象

问题描述

我有两种可以包含的文件:

  1. 对象列表
  2. 单个对象

对象列表的示例文件:

<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:getBeanListResponse xmlns:ns2="namespace">
            <beanObject>
                <fieldA>valueA</fieldA>
                <fieldB>valueB</fieldB>
                <fieldC>valueC</fieldC>
            </beanObject>
            <beanObject>
                <fieldA>valueD</fieldA>
                <fieldB>valueE</fieldB>
                <fieldC>valueF</fieldC>
            </beanObject>
            <beanObject>
                <fieldA>valueG</fieldA>
                <fieldB>valueH</fieldB>
                <fieldC>valueI</fieldC>
            </beanObject>
        </ns2:getBeanListResponse>
    </S:Body>
</S:Envelope>

单个对象的示例文件:

<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:getBeanResponse xmlns:ns2="namespace">
            <beanObject>
                <fieldA>value1</fieldA>
                <fieldB>value2</fieldB>
                <fieldC>value3</fieldC>
            </beanObject>
        </ns2:getBeanResponse>
    </S:Body>
</S:Envelope>

XPathExpression用来检索对象JaxB并将 xml 数据转换为 java 对象。对于带有对象列表的文件,我使用了表达式

//beanObject

到目前为止没有任何问题..JaxB成功地将 xml 数据转换为 java 对象。但是,在解析单个对象时我做错了。我使用了相同的 xPathExpression,但是出了点问题。这是用于对象列表的函数:

public Object getNodeListValues(String expression) {
    NodeList resultNodes;
    
    try {
        XPathExpression xPathExpression = xpath.compile(expression);
        resultNodes = (NodeList) xPathExpression.evaluate(xmlDocument, XPathConstants.NODESET);
        
        JAXBContext context = JAXBContext.newInstance(BeanObject.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        
        for (int i=0; i<resultNodes.getLength(); i++) {
            BeanObject obj = (BeanObject) unmarshaller.unmarshal(resultNodes.item(i));
            System.out.println(obj);
        }
    } catch (Exception e) {
        System.out.println(e.getMessage()); 
    }
    
    return null;
}

但我不确定如何处理单个 bean 对象。我尝试了这个函数:

public Object getNodeValue(String expression) {
        Node resultNode = null;
        try {
            XPathExpression xPathExpression = xpath.compile(expression);
            resultNode = (Node) xPathExpression.evaluate(xmlDocument, XPathConstants.NODE);
            return resultNode.getText();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        
        return null;
    }

但这给了我一个例外,说演员是不可能的:

com.sun.org.apache.xerces.internal.dom.DeferredElementNSImpl cannot be cast to org.dom4j.Node

这个问题我猜这里的节点结果是text node哪个\n 部分,但我不清楚为什么项目列表有效而这个函数不起作用..我怎样才能获得那个 xml bean 的所有值?还假设我不知道 xml 文件中对象的结构或字段。

谢谢

标签: javaxpathjaxb

解决方案


您尝试转换为org.dom4j.Node,而不是org.w3c.dom.Node。更改您的import语句或使用完全限定的类名。

编辑:由于您可能在此类中不需要 DOM4j,因此您应该拥有:

import org.w3c.dom.Node;

在序言中,您的方法应该是:

    public String getNodeValue(String expression) {
        Node resultNode = null;
        try {
            XPathExpression xPathExpression = xpath.compile(expression);
            resultNode = (Node) xPathExpression.evaluate(xmlDocument, XPathConstants.NODE);
            // DOM4j and DOM have similar methods, but with different names.
            return resultNode.getTextContent();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        
        return null;
    }

推荐阅读