无法替换节点值

时间:2018-03-21 12:58:51

标签: java xml xpath soap

我有一条SOAP消息,如字符串,如下所示:

 String testMsg = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:wsa=\"http://www.w3.org/2005/08/addressing\"><soap:Header>Some Header stuff</soap:Header><soap:Body>Some Body Stuff</soap:Body></soap:Envelope>";

然后它转到XPath但找不到一个节点(来为null)来设置文本值

    Document doc = convertStringToDocument(testMsg);
    XPath xpath = XPathFactory.newInstance().newXPath();

    String expression = "//soap:Envelope/soap:Body";
    Node node = (Node) xpath.evaluate(expression, doc, XPathConstants.NODE);

    // Set the node content
    node.setTextContent("Body was removed");

我尝试使用下面的方法将其转换为XML文档

private static Document convertStringToDocument(String xmlStr) {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);

    try
    {
        DocumentBuilder builder = factory.newDocumentBuilder();
        InputSource is = new InputSource(new StringReader(xmlStr));
        Document doc = builder.parse(is);

        return doc;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您肯定应该将问题重定向到IDE调试器。对我来说,这样的代码片段正常工作。例如,我可以在Header标签内输出文字,如此

System.out.println(
        doc.getElementsByTagNameNS("http://www.w3.org/2003/05/soap-envelope", "Header")
        .item(0).getTextContent());

输出预期的Some Header stuff。在您的情况下,我认为您打印了Document实例本身并看到了[#document: null]这样的结果让您感到困惑。但事实是,对象存在。

<强>更新 你忘了让XPath知道你的命名空间。这样就可以了。

XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new NamespaceContext() {

    @Override
    public Iterator getPrefixes(String namespaceURI) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getPrefix(String namespaceURI) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getNamespaceURI(String prefix) {
        if ("soap".equals(prefix)) {
            return "http://www.w3.org/2003/05/soap-envelope";
        }
        return null;
    }
});

String expression = "/soap:Envelope/soap:Body";
Node node = (Node) xpath.compile(expression).evaluate(doc, XPathConstants.NODE);
node.setTextContent("Body was removed");

希望它有所帮助!

答案 1 :(得分:0)

其他解决方案是设置

factory.setNamespaceAware(false);

然后将XPath代码更新为

String expression = "/Envelope/Body";
Node node = (Node) xpath.compile(expression).evaluate(doc, XPathConstants.NODE);

希望它会帮助别人。