uxpath: support de la modification de la valeur d'un noeud

This commit is contained in:
Jephté Clain 2016-06-06 00:27:58 +04:00
parent 3653f7db5a
commit f5db579658
1 changed files with 75 additions and 12 deletions

View File

@ -8,13 +8,17 @@ USAGE
OPTIONS OPTIONS
-f, --input INPUT -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 i_need_py25
import os, sys, mimetypes, types import os, sys, mimetypes, types, shutil
from os import path from os import path
from xml.dom import minidom from xml.dom import Node, minidom
from ulib.all import * from ulib.all import *
from ulib.ext import xpath from ulib.ext import xpath
@ -24,6 +28,7 @@ def display_help():
def dumprs(rs): def dumprs(rs):
tr = type(rs) tr = type(rs)
unsupported = False
if tr is types.BooleanType: if tr is types.BooleanType:
print rs and "true" or "false" print rs and "true" or "false"
elif tr is types.FloatType: elif tr is types.FloatType:
@ -32,29 +37,71 @@ def dumprs(rs):
print rs.encode("utf-8") print rs.encode("utf-8")
elif tr is types.ListType: elif tr is types.ListType:
for r in rs: dumprs(r) for r in rs: dumprs(r)
elif isinstance(rs, minidom.Element): elif isinstance(rs, Node):
nodeType = rs.nodeType
if nodeType == Node.ELEMENT_NODE:
print rs.toxml("utf-8") print rs.toxml("utf-8")
elif isinstance(rs, minidom.Attr): elif nodeType == ATTRIBUTE_NODE:
print rs.value.encode("utf-8") print rs.value.encode("utf-8")
elif isinstance(rs, minidom.Text): elif nodeType == TEXT_NODE or nodeType == CDATA_SECTION_NODE:
print rs.data.encode("utf-8") print rs.data.encode("utf-8")
else: else:
die("type non géré: %s (%s)" % (str(rs), tr)) 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(): def run_xpath():
options, longoptions = build_options([ options, longoptions = build_options([
('h', 'help', "Afficher l'aide"), ('h', 'help', "Afficher l'aide"),
('f:', 'input=', "Spécifier un fichier en entrée"), ('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) options, args = get_args(None, options, longoptions)
file = None file = None
replace = None
rewrite = False
for option, value in options: for option, value in options:
if option in ('-h', '--help'): if option in ('-h', '--help'):
display_help() display_help()
sys.exit(0) sys.exit(0)
elif option in ('-f', '--input'): elif option in ('-f', '--input'):
file = value file = value
elif option in ('-r', '--replace'):
replace = value
elif option in ('-w', '--rewrite'):
rewrite = True
if len(args) == 0: if len(args) == 0:
die("Vous devez spécifier l'expression XPATH") die("Vous devez spécifier l'expression XPATH")
@ -62,15 +109,31 @@ def run_xpath():
if file is None or file == "-": if file is None or file == "-":
inf = sys.stdin inf = sys.stdin
close = False close = False
rewrite = False
else: else:
inf = open(file, 'rb') inf = open(file, 'rb')
close = True close = True
dom = minidom.parse(inf) doc = minidom.parse(inf)
if close: inf.close() if close: inf.close()
for expr in args: 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__': if __name__ == '__main__':
run_xpath() run_xpath()