Re: Chargement DOM et attribut "xml:base"

[email protected] Fri, 11 Jan 2008 14:52:45 +0100
Newsgroups gmane.text.xml.french.tech
Message-ID <[email protected]>
...
> Ce n'est pas lié à DOM en tant que tel mais à la manière dont Xerces
> traite le problème!
Dans la spec de DOM Level 3, on trouve :
"... when external entity references are expanded
while building a Document one may need to add, or change, an xml:base attribute
to the Element nodes originally contained in the entity being expanded so that
the Node.baseURI returns the correct value."
(http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#baseURIs-Considerations)

Il me semble qu'il est normal que Xerces ajoute donc cet attribut.

>
> Je viens d'essayer les samples "dom.Counter" et "dom.Writer" xerces
> 2.9.1
...
> Il doit donc y avoir un moyen de contourner le problème en s'inspirant
> de la manière dont ces exemples sont écrits!
J'ai repris des bouts de code dans les exemples pour charger mon doc, et j'ai
comparé avec des méthodes plus standard (en suivant la norme Load and Save et
avec un bon vieux DocumentBuilder).

Voici les méthodes que j'ai utilisées :
	public static Document loadDocumentWithDOMParser(String uri)
			throws Exception {
		DOMParser parser = new DOMParser();
		parser.parse(uri);

		return parser.getDocument();
	}

	public static Document loadDocumentWithLS(String uri) throws Exception {
		DOMImplementationRegistry registry = DOMImplementationRegistry
				.newInstance();

		DOMImplementationLS impl = (DOMImplementationLS) registry
				.getDOMImplementation("LS");

		LSParser parser = impl.createLSParser(
				DOMImplementationLS.MODE_SYNCHRONOUS, null);
		parser.getDomConfig().setParameter("http://apache.org/xml/features/dom/create-entity-ref-nodes",
Boolean.TRUE);

		return parser.parseURI(uri);
	}

	public static Document loadDocumentWithDocumentBuilder(String uri)
			throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setAttribute("http://apache.org/xml/features/dom/create-entity-ref-nodes",
Boolean.TRUE);

		DocumentBuilder builder = factory.newDocumentBuilder();

		return builder.parse(uri);
	}

Le premier cas correspond à ce qui est fait dans les exemples fournis avec
Xerces.

Dans les trois cas, j'arrive au même résultat :
[(type: ELEMENT_NODE), (uri: null), (name: root), (value: null)]
    [(type: ENTITY_REFERENCE_NODE), (uri: null), (name: subdoc), (value: null)]
        [(type: TEXT_NODE), (uri: null), (name: #text), (value:
)]
        [(type: ELEMENT_NODE), (uri: null), (name: subroot), (value: null)]


pour les documents suivants :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE noeud [
<!ENTITY subdoc SYSTEM "subdoc.xml">
]>
<root>&subdoc;</root>

et subdoc.xml :
<?xml version="1.0" encoding="UTF-8"?>
<subroot></subroot>

Le problème pour moi vient du fait que le nom de l'entité apparait dans le noeud
de type ENTITY_REFERENCE_NODE, sinon ce noeud n'apparait pas (avec
http://apache.org/xml/features/dom/create-entity-ref-nodes à FALSE) et on voit
apparaître l'attribut xml:base.
C'est un problème car nous chargeons des documents pour les comparer (avec
isEqualNode) et nous souhaitions que la comparaison fasse abstraction de la
localisation des entités externes (et de leur nom).

En clair, nous aurions aimé que le document plus haut soit "égal" à celui ci (en
tout cas les noeuds racine) :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE noeud [
<!ENTITY subdoc2 SYSTEM "subdoc2.xml">
]>
<root>&subdoc2;</root>

et subdoc2.xml :
<?xml version="1.0" encoding="UTF-8"?>
<subroot></subroot>

En fait il nous aurait fallu utiliser un modèle de données plus orienté
"contenu" que DOM (à vrai dire je ne connais pas un tel modèle mais je suis
preneur si vous avez de la lecture à me conseiller), ou alors spécifier une
méthode isEqualContent() mais nous voulions au maximum éviter les
développement...

> Tenez nous au courant...
Voila !

Cordialement,

Xavier