Files
2025-09-29 00:52:08 +02:00

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()