Utilisation de XPath pour les documents XML avec un espace de noms par défaut
Lorsque vous travaillez avec des documents XML comportant un espace de noms par défaut, il peut sembler difficile d'utiliser des expressions XPath sans déclarer explicitement les URI des espaces de noms. Cependant, il existe des approches pour résoudre cette situation.
Définir Namespace Awareness sur False
Comme mentionné dans la question d'origine, la compréhension initiale était que définir namespaceAware sur false dans DocumentBuilderFactory éliminerait le besoin de travailler avec des URI d'espace de noms. Cependant, cette approche ne convient pas aux documents dotés d'un espace de noms par défaut. L'espace de noms par défaut nécessite une gestion explicite.
Utilisation de NamespaceContext
Une solution alternative consiste à utiliser un NamespaceContext lors de l'exécution de XPath. Cela vous permet d'associer des préfixes à des espaces de noms dans l'expression XPath. Les préfixes utilisés peuvent être différents de ceux définis dans le document XML.
Voici un exemple implémentant cette approche :
<code class="java">import javax.xml.namespace.NamespaceContext; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.NodeList; public class Demo { public static void main(String[] args) { DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); try { DocumentBuilder builder = domFactory.newDocumentBuilder(); Document dDoc = builder.parse("E:/test.xml"); XPath xPath = XPathFactory.newInstance().newXPath(); xPath.setNamespaceContext(new MyNamespaceContext()); NodeList nl = (NodeList) xPath.evaluate("/ns:root/ns:author", dDoc, XPathConstants.NODESET); System.out.println(nl.getLength()); } catch (Exception e) { e.printStackTrace(); } } private static class MyNamespaceContext implements NamespaceContext { public String getNamespaceURI(String prefix) { if("ns".equals(prefix)) { return "http://www.mydomain.com/schema"; } return null; } public String getPrefix(String namespaceURI) { return null; } public Iterator getPrefixes(String namespaceURI) { return null; } } }</code>
Dans cet exemple, le NamespaceContext fourni mappe le préfixe 'ns' à l'URI de l'espace de noms utilisé dans le document XML.
Expression XPath révisée
Dennis souligne à juste titre que l'expression XPath originale "/root/author" est incorrecte. Pour les documents avec un espace de noms par défaut, l'expression correcte doit être « /ns:root/ns:author ». Cela correspond aux préfixes d'espace de noms nouvellement introduits dans le code.
Simplification avec Namespace Awareness
Fait intéressant, il semble que définir namespaceAware sur true et omettre NamespaceContext fournit également le résultats souhaités. Ceci est démontré dans le code suivant :
<code class="java">import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.NodeList; public class Demo { public static void main(String[] args) { DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); try { DocumentBuilder builder = domFactory.newDocumentBuilder(); Document dDoc = builder.parse("E:/test.xml"); XPath xPath = XPathFactory.newInstance().newXPath(); NodeList nl = (NodeList) xPath.evaluate("/root/author", dDoc, XPathConstants.NODESET); System.out.println(nl.getLength()); } catch (Exception e) { e.printStackTrace(); } } }</code>
Dans ce cas, l'expression XPath familière "/root/author" peut être utilisée, car l'espace de noms du document est reconnu et implicite lors du traitement.
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!