How can I get JDOM/XPath to ignore namespaces?

痴心易碎 提交于 2019-12-01 18:25:38

I know this question is a little old, but for those viewing this later, you can override a few JDOM default classes to effectively make it ignore namespaces as well. You can pass your own JDOMFactory implementation to the SAXBuilder that ignores all Namespace values passed into it.

Then override the SAXBuilder class and implement the createContentHandler method so that it returns a SAXHandler with a blank definition for the startPrefixMapping method.

I haven't used this in a production setting so caveat emptor, but I have verified that it does work on some quick and dirty XML stuff I've done.

/ns:foo/ns:bar/@baz

becomes

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

You get the point. Don't expect that to be lightning-fast either.

Here is a jDOM2 solution that has been running in a production setting for a year with no trouble.

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;
    }

}

You can use /*:foo (XPath 2.0 or higher) or /yournamespace:* as explained here.

The first variant selects all nodes with the matching name, regardless of what namespace they belong to, including having no namespace. The latter selects all nodes belonging to a specific namespace, regardless of the node name.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!