#! /usr/bin/env python

from simplexml import *
import sys
from locale import getpreferredencoding

def help():
	print '''simplexml - command line xml navigation - Ales Smrcka (smrcka@sendmail.cz)
Syntax: simplexml command path filename.xml
Command can be:
	-v             - print data of found element(s)
        -v value       - set new data of found element(s)
        -s             - print very stripped data of found element(s)
        -a name        - print attribute value of found element(s)
        -a name=value,name2=value2 - set new values of attributes of found element(s)
        -d name        - remove attribute
        -c             - print count of matched elements
        -n name        - new element child to matched element (must be
                         only one matched element)
        -r             - remove matched elements
        -e             - extract XML of elements and print them to stdout
Path:
        Path to element(s) are element names separated by / and followed by
        optional definition of attributes (attrname1=value1,attrname2=value2)
        or index of elements [index]. Optional definition of attributes or
        element index can follow every element name. Path results to list of
        elements corresponding to the path definition.
        Path examples:
          1. path/to/element
          2. path/to(author=Ales Smrcka)/element
          3. path/to(author=Ales Smrcka)[2]/element
Examples:
        Print birth day of customer John Smith (data of element birth)
          simplexml -v "customers/customer(name=John Smith)/birth" customers.xml
        Set new modification time of third customer (data of element mtime)
          simplexml -v "2005-08-15 12:00" customers/customer[2]/mtime customers.xml
        Print all customer names (attribute name)
          simplexml -a name customers/customer customers.xml
        Set new customer name:
          simplexml -a "name=George Smith" "customers/customer(name=John Smith)" customers.xml
'''
	sys.exit(1)

def xmlopen(filename):
	try:
		return xmldoc(filename)
	except:
		print 'simplexml: Could not open file %s' % filename
		sys.exit(2)

def main():
	argc = len(sys.argv)
	if argc<2: help()
	enc = getpreferredencoding()
	for i in range(len(sys.argv)):
		sys.argv[i] = sys.argv[i].decode(enc)
	if sys.argv[1] == '-c':
		# print count of matched elements
		# -c path filename
		if argc<4: help()
		d = xmlopen(sys.argv[3])
		print len(d.elements(sys.argv[2]))
	elif sys.argv[1] == '-e':
		# print XML form of matched elements
		# -e path filename
		if argc<4: help()
		d = xmlopen(sys.argv[3])
		for element in d.elements(sys.argv[2]):
			print element.toxml()
	elif sys.argv[1] == '-s':
		# print value of elements
		# -s path filename
		if argc<4: help()
		d = xmlopen(sys.argv[3])
		for element in d.elements(sys.argv[2]):
			print element.value
	elif sys.argv[1] == '-v':
		# print or set data of elements
		# -v [value] path filename
		if argc<4: help()
		elif argc==4:
			# -v path filename
			d = xmlopen(sys.argv[3])
			for element in d.elements(sys.argv[2]):
				print element.data
		else:
			# -v value path filename
			d = xmlopen(sys.argv[4])
			for element in d.elements(sys.argv[3]):
				element.set_value(sys.argv[2])
			d.save()
	elif sys.argv[1] == '-r':
		# remove matched elements
		# -r path filename
		if argc<4: help()
		d = xmlopen(sys.argv[3])
		for element in d.elements(sys.argv[2]):
			element.remove()
		d.save()
	elif sys.argv[1] == '-n':
		# create new child to just one matched element
		# -n name path filename
		if argc<5: help()
		d = xmlopen(sys.argv[4])
		matched = d.elements(sys.argv[3])
		if len(matched)>1:
			print 'Path must match just one element'
			return 1
		elif len(matched)==0:
			print 'Path must match at least one element'
			return 1
		matched[0].newchild(sys.argv[2])
		d.save()
	elif sys.argv[1] == '-a':
		# print or set attribute of elements
		# -a attrname[=value] path filename
		if argc<5: help()
		d = xmlopen(sys.argv[4])
		aset=[]
		for adef in sys.argv[2].split(','):
			adef = adef.split('=')
			if len(adef)==2:
				aset.append(adef)
		if aset:
			# set attributes
			for element in d.elements(sys.argv[3]):
				for a in aset:
					element.attr(a[0], a[1])
			d.save()
		else:
			# print attribute
			for element in d.elements(sys.argv[3]):
				print element.attr(sys.argv[2])
	elif sys.argv[1] == '-d':
		# remove attribute from all found elements
		# -d name path filename
		if argc<5: help()
		d = xmlopen(sys.argv[4])
		for element in d.elements(sys.argv[3]):
			element.removeattr(sys.argv[2])
		d.save()
	return 0

if __name__ == "__main__":
	sys.exit(main())
