Consultar XML com namespaces em Java usando XPath
Ao trabalhar com documentos XML contendo elementos vinculados a namespaces, consultar com XPath pode se tornar um desafio. Considere o seguinte exemplo:
O uso de uma expressão XPath padrão "sem namespace" como "/workbook/sheets/sheet[1]" falhará. Isso ocorre porque os elementos no documento XML estão vinculados a um namespace, que não é considerado na expressão XPath.
Solução 1: registrar namespace e usar prefixo de namespace
A abordagem recomendada é registrar o namespace com um prefixo de namespace, tornando o XPath mais fácil de ler e manter:
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);
Usando o prefixo de namespace, a expressão XPath se torna "/main:workbook/main:sheets/main:sheet[1]", que aborda corretamente os elementos vinculados ao namespace especificado.
Solução 2: Correspondência genérica e filtro de predicado
Alternativamente, uma expressão XPath sem um prefixo de namespace pode ser construída usando uma correspondência genérica para o elemento e um filtro de predicado que especifica o nome local desejado() e 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);
Este método é detalhado e pode apresentar riscos se vocabulários mistos estiverem presentes no documento XML.
Conclusão
Ao lidar com documentos XML com namespaces, é essencial considerar as ligações de namespace. Registrando o namespace com um prefixo ou elaborando cuidadosamente expressões XPath genéricas, consultas precisas e confiáveis podem ser realizadas.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3