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

发布于 2024-08-28 10:20:05 字数 129 浏览 6 评论 0原文

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

I need to process an XML DOM, preferably with JDOM, where I can do XPath search on nodes. I know the node names or paths, but I want to ignore namespaces completely because sometimes the document comes with namespaces, sometimes without, and I can't rely on specific values. Is that possible? How?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

请止步禁区 2024-09-04 10:20:05
/ns:foo/ns:bar/@baz

变成

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

你明白了。也不要指望它会快如闪电。

/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.

爱人如己 2024-09-04 10:20:05

我知道这个问题有点老了,但是对于那些稍后查看这个问题的人来说,您可以覆盖一些 JDOM 默认类以有效地使其也忽略名称空间。您可以将自己的 JDOMFactory 实现传递给 SAXBuilder,该 SAXBuilder 会忽略传递到其中的所有命名空间值。

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

我还没有在生产环境中使用过它,所以买者自负,但我已经验证它确实适用于我所做的一些快速而肮脏的 XML 东西。

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.

多情出卖 2024-09-04 10:20:05

这是一个 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;
    }

}

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

}
弥繁 2024-09-04 10:20:05

您可以使用 /*:foo (XPath 2.0 或更高版本)或 /yournamespace:* 如此处解释

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文