Как я могу заставить JDOM / XPath игнорировать пространства имен? - PullRequest
5 голосов
/ 09 апреля 2010

Мне нужно обработать XML DOM, предпочтительно с JDOM, где я могу выполнять поиск XPath по узлам. Я знаю имена узлов или пути, но я хочу игнорировать пространства имен полностью , потому что иногда документ поставляется с пространствами имен, иногда без, и я не могу полагаться на конкретные значения. Это возможно? Как?

Ответы [ 4 ]

17 голосов
/ 09 апреля 2010
/ns:foo/ns:bar/@baz

становится

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

Ты понял. Не ожидайте, что это будет молниеносно.

3 голосов
/ 09 мая 2014

Вот решение 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;
    }

}
3 голосов
/ 25 ноября 2010

Вы можете использовать /*:foo (XPath 2.0 или выше) или /yournamespace:* , как описано здесь .

Первый вариант выбирает все узлы с совпадающим именем, независимо от того, к какому пространству имен они принадлежат, включая отсутствие пространства имен. Последний выбирает все узлы, принадлежащие определенному пространству имен, независимо от имени узла.

3 голосов
/ 18 мая 2010

Я знаю, что этот вопрос немного устарел, но для тех, кто просматривает его позже, вы можете переопределить несколько классов JDOM по умолчанию, чтобы эффективно игнорировать пространства имен. Вы можете передать свою собственную реализацию JDOMFactory в SAXBuilder, который игнорирует все значения пространства имен, переданные в него.

Затем переопределите класс SAXBuilder и реализуйте метод createContentHandler, чтобы он возвращал SAXHandler с пустым определением для метода startPrefixMapping.

Я не использовал это в производственных условиях, так что будьте бдительны, но я убедился, что он работает на некоторых быстрых и грязных XML-материалах, которые я сделал.

...