javax.xml,XPath不是从带有名称空间的XML中提取的 [英] javax.xml, XPath is not extracted from XML with namespaces

查看:108
本文介绍了javax.xml,XPath不是从带有名称空间的XML中提取的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有原始XML

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
    <soap:Header>
        <context xmlns="urn:zimbra">
            <session id="555">555</session>
            <change token="333"/>
        </context>
    </soap:Header>
    <soap:Body>
        <AuthResponse xmlns="urn:zimbraAccount">
            <lifetime>172799999</lifetime>
            <session id="555">555</session>
            <skin>carbon</skin>
        </AuthResponse>
    </soap:Body>
</soap:Envelope>

以这种方式解析XML

The XML is parsed in this way

// javax.xml.parsers.*
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(pathToXml);

然后我试图通过XPath提取会话ID

Then I'm trying to extract session id by XPath

// javax.xml.xpath.*;
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
// next xpath does not work with Java and online xpath tester
//XPathExpression expr = xpath.compile("/soap:Envelope/soap:Header/context/session/text()");
// this xpath works with online xpath tester but does not with in Java
XPathExpression expr = xpath.compile("/soap:Envelope/soap:Header/*[name()='context']/*[name()='session']/text()");
String sessionId = (String)expr.evaluate(doc, XPathConstants.STRING);

此处测试
http://www.xpathtester.com/xpath/678ae9388e3ae2fc8406eb8cf14f3119

当XML简化为此

<Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
    <Header>
        <context>
            <session id="555">555</session>
            <change token="333"/>
        </context>
    </Header>
    <Body>
        <AuthResponse xmlns="urn:zimbraAccount">
            <lifetime>172799999</lifetime>
            <session id="555">555</session>
            <skin>carbon</skin>
        </AuthResponse>
    </Body>
</Envelope>

此XPath完成其工作

This XPath does its job

XPathExpression expr = xpath.compile("/Envelope/Header/context/session/text()");

如何使用Java从原始XML中提取会话ID?

How to extract session id from "original" XML with Java?

更新:JDK 1.6

UPDATE: JDK 1.6

推荐答案

答案是你需要正确使用名称空间和名称空间前缀

首先,在使用它之前调用它来识别你的 DocumentBuilderFactory 名称空间:

First, make your DocumentBuilderFactory namespace aware by calling this before you use it:

factory.setNamespaceAware(true); 

然后执行此操作以检索所需的值:

Then do this to retrieve the value you want:

XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
xpath.setNamespaceContext(new NamespaceContext() {
    @Override
    public String getNamespaceURI(String prefix) {
        if (prefix.equals("soap")) {
            return "http://www.w3.org/2003/05/soap-envelope";
        }
        if (prefix.equals("zmb")) {
            return "urn:zimbra";
        }

        return XMLConstants.NULL_NS_URI;
    }

    @Override
    public String getPrefix(String namespaceURI) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Iterator getPrefixes(String namespaceURI) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
});

XPathExpression expr = 
       xpath.compile("/soap:Envelope/soap:Header/zmb:context/zmb:session");
String sessionId = (String)expr.evaluate(doc, XPathConstants.STRING);

您可能需要在文件的开头添加一行来导入NamespaceContext类:

You may need to add a line to the beginning of your file to import the NamespaceContext class:

import javax.xml.namespace.NamespaceContext;

http://ideone.com/X3iX5N

这篇关于javax.xml,XPath不是从带有名称空间的XML中提取的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆