【问题标题】:Identify XML by xmlns in XPath通过 XPath 中的 xmlns 识别 XML
【发布时间】:2013-01-14 17:29:01
【问题描述】:

如何在 Java 中使用 XPath 区分这两个 XML?

<iq type="result">
    <query xmlns="jabber:iq:roster">
    </query>
</iq>

<iq type="result">
    <query xmlns="vcard-temp">
    </query>
</iq>

我试过了,它总是打印空,

public class Test {

    public static void main(String[] args) throws Exception {
        final String xml = "<iq type=\"result\"><query xmlns=\"jabber:iq:roster\"></query></iq>";

        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document document = builder.parse(createInputSource(xml));

        XPath xpath = XPathFactory.newInstance().newXPath();
        xpath.setNamespaceContext(new NamespaceContext() {
            @Override
            public String getNamespaceURI(String prefix) {
                switch (prefix) {
                    case "roster":
                        return "jabber:iq:roster";
                    case "vcard":
                        return "vcard-temp";
                }

                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.");
            }
        });

        Node match = (Node) xpath.evaluate("/iq/roster:query", document, XPathConstants.NODE);
        System.out.println(match);
    }

    private static InputSource createInputSource(String xml) {
        return new InputSource(new StringReader(xml));
    }
}

【问题讨论】:

  • 我错过了 setNamespaceAware()。现在可以使用了。

标签: java xml xpath xml-namespaces


【解决方案1】:

您使用 XPath 查询 XML 文档的任何 API 很可能都有为命名空间注册命名空间前缀的方法,例如使用 NamespaceContext
因此,您可以为每个命名空间分配不同的前缀,并使用以下内容检索相应的节点:

/iq/jRoster:query
/iq/vcard:query

另一种选择是跳过 NamespaceContext 并使用 namespace-uri():

/iq/*[local-name() = "query" and namespace-uri() = "jabber:iq:roster"]
/iq/*[local-name() = "query" and namespace-uri() = "vcard-temp"]

看起来您还需要在创建文档构建器时使用 setNamespaceAware(true):

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();

【讨论】:

    猜你喜欢
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多