Interroger XML avec des espaces de noms en Java à l'aide de XPath
Lorsque vous travaillez avec des documents XML contenant des éléments liés à des espaces de noms, les requêtes avec XPath peuvent devenir difficiles. Prenons l'exemple suivant :
L'utilisation d'une expression XPath par défaut "sans espace de noms" telle que "/workbook/sheets/sheet[1]" échouera. En effet, les éléments du document XML sont liés à un espace de noms, qui n'est pas pris en compte dans l'expression XPath.
Solution 1 : enregistrer l'espace de noms et utiliser le préfixe d'espace de noms
L'approche recommandée consiste à enregistrer l'espace de noms avec un préfixe d'espace de noms, ce qui rend XPath plus facile à lire et à maintenir :
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);
En utilisant le préfixe d'espace de noms, l'expression XPath devient "/main:workbook/main:sheets/main:sheet[1]", qui adresse correctement les éléments liés à l'espace de noms spécifié.
Solution 2 : correspondance générique et filtre de prédicat
Alternativement, une expression XPath sans préfixe d'espace de noms peut être construite en utilisant une correspondance générique pour l'élément et un filtre de prédicat qui spécifie le nom local() et l'espace de noms souhaités :
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);
Cette méthode est verbeuse et peut présenter des risques si des vocabulaires mixtes sont présents dans le document XML.
Conclusion
Lorsque vous traitez des documents XML avec des espaces de noms, il est essentiel de prendre en compte les liaisons d'espaces de noms. En enregistrant l'espace de noms avec un préfixe ou en créant soigneusement des expressions XPath génériques, des requêtes précises et fiables peuvent être effectuées.
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3