Запрос XML с пространствами имен в Java с использованием XPath
При работе с XML-документами, содержащими элементы, привязанные к пространствам имен, выполнение запросов с помощью XPath может оказаться затруднительным. Рассмотрим следующий пример:
Использование выражения XPath по умолчанию «без пространства имен», например «/workbook/sheets/sheet[1]», приведет к сбою. Это связано с тем, что элементы в XML-документе привязаны к пространству имен, которое не учитывается в выражении XPath.
Решение 1. Зарегистрируйте пространство имен и используйте префикс пространства имен
Рекомендуемый подход — зарегистрировать пространство имен с помощью префикса пространства имен, что упрощает чтение и поддержку XPath:
NamespaceContext namespaceContext = new NamespaceContext() { @Override public String getNamespaceURI(String prefix) { if (prefix.equals("main")) { return "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; } else if (prefix.equals("r")) { return "http://schemas.openxmlformats.org/officeDocument/2006/relationships"; } return null; } }; XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath(); xPath.setNamespaceContext(namespaceContext); NodeList nodes = (NodeList) xPath.evaluate("/main:workbook/main:sheets/main:sheet[1]", document, XPathConstants.NODESET);
Используя префикс пространства имен, выражение XPath принимает вид «/main:workbook/main:sheets/main:sheet[1]», который правильно адресует элементы, привязанные к указанному пространству имен.
Решение 2. Общий фильтр совпадений и предикатов
В качестве альтернативы выражение XPath без префикса пространства имен может быть создано с использованием общего соответствия для элемента и фильтра предикатов, который определяет желаемые local-name() и namespace-uri():
XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath(); NodeList nodes = (NodeList) xPath.evaluate("/*[local-name()='workbook' and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main']" "/*[local-name()='sheets' and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main']" "/*[local-name()='sheet' and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main'][1]", document, XPathConstants.NODESET);
Этот метод является многословным и может представлять опасность, если в XML-документе присутствуют смешанные словари.
Заключение
При работе с XML-документами с пространствами имен важно учитывать привязки пространств имен. Зарегистрировав пространство имен с помощью префикса или тщательно создав общие выражения XPath, можно выполнять точные и надежные запросы.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3