From f5db579658f9b7efb2b0ccf241591c712c6b09a0 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Mon, 6 Jun 2016 00:27:58 +0400 Subject: [PATCH] uxpath: support de la modification de la valeur d'un noeud --- lib/pyulib/src/uapps/uxpath.py | 87 +++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 12 deletions(-) diff --git a/lib/pyulib/src/uapps/uxpath.py b/lib/pyulib/src/uapps/uxpath.py index db0141b..37be711 100755 --- a/lib/pyulib/src/uapps/uxpath.py +++ b/lib/pyulib/src/uapps/uxpath.py @@ -8,13 +8,17 @@ USAGE OPTIONS -f, --input INPUT - Spécifier un fichier en entrée""" + 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 +import os, sys, mimetypes, types, shutil from os import path -from xml.dom import minidom +from xml.dom import Node, minidom from ulib.all import * from ulib.ext import xpath @@ -24,6 +28,7 @@ def display_help(): def dumprs(rs): tr = type(rs) + unsupported = False if tr is types.BooleanType: print rs and "true" or "false" elif tr is types.FloatType: @@ -32,29 +37,71 @@ def dumprs(rs): print rs.encode("utf-8") elif tr is types.ListType: for r in rs: dumprs(r) - elif isinstance(rs, minidom.Element): - print rs.toxml("utf-8") - elif isinstance(rs, minidom.Attr): - print rs.value.encode("utf-8") - elif isinstance(rs, minidom.Text): - print rs.data.encode("utf-8") + 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: - die("type non géré: %s (%s)" % (str(rs), tr)) + 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") @@ -62,15 +109,31 @@ def run_xpath(): if file is None or file == "-": inf = sys.stdin close = False + rewrite = False else: inf = open(file, 'rb') close = True - dom = minidom.parse(inf) + doc = minidom.parse(inf) if close: inf.close() for expr in args: - dumprs(xpath.find(expr, dom)) + 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()