Maison  >  Article  >  Java  >  Comment gérer des documents XML avec un espace de noms par défaut à l'aide de XPath ?

Comment gérer des documents XML avec un espace de noms par défaut à l'aide de XPath ?

Patricia Arquette
Patricia Arquetteoriginal
2024-10-24 07:00:02994parcourir

How to Handle XML Documents with Default Namespace Using XPath?

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn