Dans les cas où votre XML contient des espaces de noms, comme dans cet exemple :
<?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>
vous pouvez rencontrer des problèmes lors de l'utilisation de requêtes XPath telles que "/classeur/feuilles/feuille[1]". En effet, les éléments sont liés à un espace de noms et votre XPath recherche des éléments dans l'espace de noms anonyme par défaut.
Il existe plusieurs façons de gérer les espaces de noms dans les requêtes XPath :
L'approche recommandée consiste à enregistrer l'espace de noms avec un préfixe. Cela simplifie le développement et la maintenance de XPath :
NamespaceContext namespaceContext = new NamespaceContext() { @Override public String getNamespaceURI(String prefix) { if ("xssf".equals(prefix)) { return "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; } return null; } @Override public String getPrefix(String namespaceURI) { return null; } @Override public Iterator getPrefixes(String namespaceURI) { return null; } }; XPath xpath = XPathFactory.newInstance().newXPath(); xpath.setNamespaceContext(namespaceContext);
Avec cette configuration, vous pouvez utiliser des requêtes XPath simplifiées :
/xssf:workbook/xssf:sheets/xssf:sheet[1]
Si vous préférez ne pas utiliser de préfixes d'espace de noms, vous pouvez créer des expressions XPath qui utilisent une correspondance générique avec un filtre de prédicat :
/*[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]
Cette méthode génère des expressions XPath détaillées qui peuvent être difficiles à lire et à maintenir.
Vous pouvez également ignorer les espaces de noms en faisant correspondre uniquement sur le site local name :
/*[local-name()='workbook']/*[local-name()='sheets']/*[local-name()='sheet'][1]
Cependant, cette approche risque de sélectionner les mauvais éléments dans les cas de vocabulaires mixtes qui utilisent les mêmes noms locaux dans différents espaces de noms.
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!