165 lines
4.4 KiB
Python
Executable File
165 lines
4.4 KiB
Python
Executable File
# reorder XML attributes
|
|
|
|
import sys
|
|
from xml.sax import saxutils, handler, make_parser
|
|
from StringIO import StringIO
|
|
|
|
ParserSchemaOrderTable = [
|
|
u"xmlns:xsi",
|
|
u"xsi:noNamespaceSchemaLocation",
|
|
u"name",
|
|
u"type",
|
|
u"base",
|
|
u"generate",
|
|
u"value",
|
|
u"size",
|
|
u"sizeVar",
|
|
u"indexBits",
|
|
u"init",
|
|
u"min",
|
|
u"max",
|
|
u"step",
|
|
u"key",
|
|
u"enumKeyType",
|
|
u"enumKeySize",
|
|
u"numBits",
|
|
u"values",
|
|
u"policy",
|
|
u"toString",
|
|
u"fromString",
|
|
u"version",
|
|
u"simple",
|
|
u"constructable",
|
|
u"constructible",
|
|
u"template",
|
|
u"usesdi",
|
|
u"highPrecision",
|
|
u"addGroupWidget",
|
|
u"noInit",
|
|
u"onUnknownType",
|
|
u"userHandlesNull",
|
|
u"onWidgetChanged"
|
|
u"onPreLoad",
|
|
u"onPostLoad",
|
|
u"onPreSave",
|
|
u"onPostSave",
|
|
u"onPreAddWidgets",
|
|
u"onPostAddWidget",
|
|
u"onPreSet",
|
|
u"onPostSet",
|
|
u"preserveNames",
|
|
u"ui_key",
|
|
u"cond",
|
|
u"hideFrom",
|
|
u"hideWidgets",
|
|
u"autoregister",
|
|
u"platform",
|
|
u"description",
|
|
]
|
|
|
|
ParserSchemaOrderMap = dict([(str, idx) for (idx, str) in enumerate(ParserSchemaOrderTable)])
|
|
|
|
def ParserSchemaAttributeOrdering(attr1, attr2):
|
|
name1 = attr1[0]
|
|
name2 = attr2[0]
|
|
order1 = ParserSchemaOrderMap.get(name1, 10000)
|
|
order2 = ParserSchemaOrderMap.get(name2, 10000)
|
|
if (order1 == order2):
|
|
return cmp(name1, name2)
|
|
return cmp(order1, order2)
|
|
|
|
# based on roundtrip.py from http://mail.python.org/pipermail/python-dev/2000-October/009946.html
|
|
|
|
class ContentGenerator(handler.ContentHandler):
|
|
|
|
def __init__(self, out = sys.stdout):
|
|
handler.ContentHandler.__init__(self)
|
|
self._out = out
|
|
self.justStartedElement = False
|
|
self.inFakeComment = False
|
|
|
|
# ContentHandler methods
|
|
|
|
def startDocument(self):
|
|
self._out.write('<?xml version="1.0"?>\n')
|
|
|
|
def startElement(self, name, attrs):
|
|
self._out.write('<' + name)
|
|
|
|
sortedItems = sorted(attrs.items(), cmp=ParserSchemaAttributeOrdering)
|
|
|
|
for (name, value) in sortedItems:
|
|
self._out.write(' %s="%s"' % (name, saxutils.escape(value)))
|
|
self.justStartedElement = True
|
|
|
|
if name == "xml:fakecomment":
|
|
self.inFakeComment = True
|
|
self.justStartedElement = False
|
|
self._out.write("><![CDATA[")
|
|
|
|
def endElement(self, name):
|
|
if self.inFakeComment:
|
|
self.inFakeComment = False
|
|
self._out.write("]]>")
|
|
|
|
if self.justStartedElement:
|
|
self.justStartedElement = False
|
|
self._out.write("/>")
|
|
else:
|
|
self._out.write('</%s>' % name)
|
|
|
|
|
|
def characters(self, content):
|
|
if self.justStartedElement:
|
|
self.justStartedElement = False
|
|
self._out.write(">")
|
|
if self.inFakeComment:
|
|
self._out.write(content) # do not escape, we're in a CDATA block
|
|
else:
|
|
self._out.write(saxutils.escape(content))
|
|
|
|
def ignorableWhitespace(self, content):
|
|
if self.justStartedElement:
|
|
self.justStartedElement = False
|
|
self._out.write(">")
|
|
self._out.write(content)
|
|
|
|
def processingInstruction(self, target, data):
|
|
if self.justStartedElement:
|
|
self.justStartedElement = False
|
|
self._out.write(">")
|
|
self._out.write('<?%s %s?>' % (target, data))
|
|
|
|
#################################################################
|
|
|
|
fileData = file(sys.argv[1]).read()
|
|
|
|
# make multiple passes over the file
|
|
|
|
# convert all XML comments into XML tags (otherwise the sax parser will strip them)
|
|
fileData = fileData.replace(r"<!--", r"<xml:fakecomment><![CDATA[")
|
|
fileData = fileData.replace(r"-->", r"]]></xml:fakecomment>")
|
|
|
|
# reorder all attributes
|
|
dataStream = StringIO(fileData)
|
|
outStream = StringIO()
|
|
|
|
parser = make_parser()
|
|
parser.setContentHandler(ContentGenerator(outStream))
|
|
parser.parse(dataStream)
|
|
|
|
outStream.seek(0)
|
|
fileData = outStream.read()
|
|
|
|
# un-convert the comments
|
|
fileData = fileData.replace(r"<xml:fakecomment><![CDATA[", r"<!--")
|
|
fileData = fileData.replace(r"]]></xml:fakecomment>", r"-->")
|
|
sys.stderr.write(fileData)
|
|
|
|
# done, write results
|
|
outFile = file(sys.argv[2], "w")
|
|
outFile.write(fileData)
|
|
outFile.close()
|
|
|
|
|