#!/usr/bin/env python # -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 u"""%(scriptname)s: Faire une requête xpath USAGE %(scriptname)s -f input expr OPTIONS -f, --input INPUT Spécifier un fichier en entrée -r, --replace VALUE Remplacer le contenu des noeuds trouvés par la valeur spécifiée. -w, --rewrite Re-écrire l'arbre modifié dans le fichier d'origine.""" import i_need_py25 import os, sys, mimetypes, types, shutil from os import path from xml.dom import Node, minidom from ulib.all import * from ulib.ext import xpath def display_help(): uprint(__doc__ % globals()) def dumprs(rs): tr = type(rs) unsupported = False if tr is types.BooleanType: print rs and "true" or "false" elif tr is types.FloatType: print rs elif tr is types.UnicodeType: print rs.encode("utf-8") elif tr is types.ListType: for r in rs: dumprs(r) elif isinstance(rs, Node): nodeType = rs.nodeType if nodeType == Node.ELEMENT_NODE: print rs.toxml("utf-8") elif nodeType == ATTRIBUTE_NODE: print rs.value.encode("utf-8") elif nodeType == TEXT_NODE or nodeType == CDATA_SECTION_NODE: print rs.data.encode("utf-8") else: unsupported = True else: unsupported = True if unsupported: die("type non géré pour l'affichage: %s (%s)" % (str(rs), tr)) def updaters(rs, value, doc): tr = type(rs) unsupported = False if tr is types.ListType: for r in rs: updaters(r, value, doc) elif isinstance(rs, Node): nodeType = rs.nodeType if nodeType == Node.ELEMENT_NODE: firstChild = rs.firstChild textNode = doc.createTextNode(value) if firstChild is None: rs.appendChild(textNode) elif firstChild.nodeType == Node.TEXT_NODE or \ firstChild.nodeType == Node.CDATA_SECTION_NODE: rs.replaceChild(textNode, firstChild) else: rs.insertBefore(textNode, firstChild) elif nodeType == ATTRIBUTE_NODE: rs.value = value elif nodeType == TEXT_NODE or nodeType == CDATA_SECTION_NODE: rs.data = value else: unsupported = True else: unsupported = True if unsupported: die("type non géré pour la mise à jour: %s (%s)" % (str(rs), tr)) def run_xpath(): options, longoptions = build_options([ ('h', 'help', "Afficher l'aide"), ('f:', 'input=', "Spécifier un fichier en entrée"), ('r:', 'replace=', "Remplacer la valeur des noeuds par celle spécifiée"), ('w', 'rewrite', "Reécrire le résultat dans le fichier original"), ]) options, args = get_args(None, options, longoptions) file = None replace = None rewrite = False for option, value in options: if option in ('-h', '--help'): display_help() sys.exit(0) elif option in ('-f', '--input'): file = value elif option in ('-r', '--replace'): replace = value elif option in ('-w', '--rewrite'): rewrite = True if len(args) == 0: die("Vous devez spécifier l'expression XPATH") if file is None or file == "-": inf = sys.stdin close = False rewrite = False else: inf = open(file, 'rb') close = True doc = minidom.parse(inf) if close: inf.close() for expr in args: rs = xpath.find(expr, doc) if replace is None: dumprs(rs) else: updaters(rs, replace, doc) if replace is not None: if rewrite: outf, tempf = mktemp() close = True else: outf = sys.stdout close = False doc.writexml(outf, encoding='utf-8') if close: outf.close() shutil.copyfile(tempf, file) cltemp() if __name__ == '__main__': run_xpath()