如何让JDOM / XPath忽略命名空间?

时间:2010-04-09 12:40:35

标签: xml xpath namespaces ignore jdom

我需要处理XML DOM,最好是使用JDOM,我可以在节点上进行XPath搜索。我知道节点名称或路径,但我想忽略名称空间完全,因为有时文档带有名称空间,有时没有,我不能依赖于特定的值。那可能吗?怎么样?

4 个答案:

答案 0 :(得分:17)

/ns:foo/ns:bar/@baz

变为

/*[local-name() = 'foo']/*[local-name() = 'bar']/@baz

你明白了。不要指望它也是闪电般的。

答案 1 :(得分:3)

我知道这个问题有点旧,但对于那些稍后查看的人,你可以覆盖一些JDOM默认类来有效地使它忽略命名空间。您可以将自己的JDOMFactory实现传递给SAXBuilder,它忽略传递给它的所有Namespace值。

然后重写SAXBuilder类并实现createContentHandler方法,以便它返回一个SAXHandler,其中包含startPrefixMapping方法的空白定义。

我没有在生产设置中使用过这个警告,但是我已经证实它确实可以处理我已经完成的一些快速和脏的XML。

答案 2 :(得分:3)

您可以使用/*:foo(XPath 2.0或更高版本)或/yournamespace:* as explained here

第一个变体选择具有匹配名称的所有节点,无论它们属于哪个命名空间,包括没有命名空间。后者选择属于特定命名空间的所有节点,而不管节点名称。

答案 3 :(得分:3)

这是一个jDOM2解决方案, 已在生产环境中运行一年,没有任何问题。

public class JdomHelper {

    private static final SAXHandlerFactory FACTORY = new SAXHandlerFactory() {
        @Override
        public SAXHandler createSAXHandler(JDOMFactory factory) {
            return new SAXHandler() {
                @Override
                public void startElement(
                        String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
                    super.startElement("", localName, qName, atts);
                }
                @Override
                public void startPrefixMapping(String prefix, String uri) throws SAXException {
                    return;
                }
            };
        }
    };


    /** Get a {@code SAXBuilder} that ignores namespaces.
     * Any namespaces present in the xml input to this builder will be omitted from the resulting {@code Document}. */
    public static SAXBuilder getSAXBuilder() {
        // Note: SAXBuilder is NOT thread-safe, so we instantiate a new one for every call.
        SAXBuilder saxBuilder = new SAXBuilder();
        saxBuilder.setSAXHandlerFactory(FACTORY);
        return saxBuilder;
    }

}