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 interrogations avec XPath peuvent devenir difficiles. Prenons l'exemple suivant :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> <sheets> <sheet name="Sheet1" sheetId="1" r:id="rId1"/> </sheets> </workbook>
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 : Match générique et filtre de prédicat
Alternativement, une expression XPath sans un préfixe d'espace de noms peut être construit en utilisant une correspondance générique pour l'élément et un filtre de prédicat qui spécifie le local-name() et le namespace-uri() 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 détaillée et peut présenter 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.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!