Tests XPath

Le but est de tester l'utilisation des expressions XPath avec les espaces de noms. Le fonctionnement du test est le suivant :

Le programme

Pour réaliser ce test, deux API sont utilisées. La première est JAXEN, la seconde XALAN.Il est nécessaire de fournir un préfixe pour l'espace de noms par défaut, celui-ci n'en possédant pas. Le document d'accueil du W3c est écrit en XHTML, il s'agit donc de XML bien formé. Le préfixe par défaut est http://www.w3.org/1999/xhtml. En lui associant html, la requête permettant de connaître le texte du titre le plus récent est (à partir de la page d'accueil html) :

//html:h3[@class="headline"].

Le programme se charge alors d'évaluer cette expression et d'afficher le résultat.

 html
XPath to evaluate -> //html:h3[@class='headline']/text()
Evaluate Xpath :  //html:h3[@class='headline']/text()
1  results
---------------
[#text: Scalable Vector Graphics (SVG) 1.1 and Mobile SVG
Are W3C Recommendations]
]]>

Code commun

La lecture du document se fait par un chargement DOM classique (en utilisant JAXP du jdk). Les deux API travaillent ensuite sur le document en mémoire.

Lors du chargement du document, il y a une construction d'une table contenant les espaces de noms définis par le document. Cette table servira par la suite à aider le processeur xpath à bien évaluer la requète. Ce traitement est réalisé par la classe DocumentReader (fichier docreader.py)

La lecture du document XML (premier paramètre de la ligne de commande) se fait ainsi :

# read the xml document
dr = docreader.DocumentReader()
dr.read(sys.argv[1])	
	

Test avec Jaxen

Il faut fournir à jaxen l'ensemble des espaces de noms avant l'évaluation de l'expression. Cela est possible grace à la méthode addNamespace. La selection se fait via la méthode selectNodes.

# make the selection
xpath = DOMXPath(xp)
for k in dr.namespace.keys():
	xpath.addNamespace(k,dr.namespace[k])
results = xpath.selectNodes(dr.doc)
	

Le résultat est stocké dans une java.util.List qu'il suffit de parcourir pour afficher les résultats :

# display results
print len(results), " results"
for r in results:
	print "%s\n%s"%("-"*15,r)
	

Test avec Xalan

Xalan requiert un noeud comportant les espaces de noms à utiliser. Pour ce faire, un nouveau document DOM est créé. Celui-ci ne sert qu'à supporter les espaces de noms. Une fois créé, avec la fabrique JAXP, les espaces de noms lui sont rajoutés, et le noeud racine du document fourni à la méthode chargée de faire l'évaluation XPath.

# create a new document for the namespace support
dbf = DocumentBuilderFactory.newInstance()
impl = dbf.newDocumentBuilder().getDOMImplementation()
(prefix, uri) = dr.defaultnamespace
nsdoc = impl.createDocument(uri, prefix, None)
root = nsdoc.getDocumentElement()
for ns in dr.namespace.keys():
	root.setAttributeNS("http://www.w3.org/2000/xmlns/",
			    "xmlns:%s"%ns, dr.namespace[ns])	
	

Les résultats se présentent sous la forme d'une liste de noeud classique (org.w3c.dom.NodeList), qu'il suffit de parcourir.

# make the selection
results = XPathAPI.selectNodeList(dr.doc, xp, root)

# print result
print "res : ",results.getLength()
for i in range(0,results.getLength()):
	value = XPathAPI.eval(results.item(i), "string()");
	print value.str()
	
	

Langages

Xapth, Jaxen, Xalan

Programmes