Skip to content

Instantly share code, notes, and snippets.

@treeform
Created February 12, 2013 18:13
Show Gist options
  • Save treeform/4771953 to your computer and use it in GitHub Desktop.
Save treeform/4771953 to your computer and use it in GitHub Desktop.
Gruling XML library i wrote.
"""
Example user case:
define rules:
rules = [
("library_images / image id / init_from / *", image),
("library_effects / effect id / profile_COMMON / newparam sid / sampler2D / source / *", effect),
("library_materials / material id name / instance_effect url", material),
("node id name / ...", node),
("node id / translate sid / *", ch),
("node id / rotate sid / *", ch),
("node id / scale sid / *", ch),
("node id / instance_geometry url", geomurl),
("node id / instance_geometry / bind_material / technique_common / instance_material target", mat),
("library_geometries / geometry id", geometry),
("library_geometries / geometry id / mesh / source id / float_array / *", float_array),
("library_geometries / geometry id / mesh / vertices id / input semantic source", vertices),
("library_geometries / geometry id / mesh / polylist / input offset semantic source", polylist_input),
("library_geometries / geometry id / mesh / polylist / vcount / *", polylist_vcount),
("library_geometries / geometry id / mesh / polylist / p / *", polylist_p),
]
parse the file
GrulingXML(rules, in_file)
"""
import xml.sax
class Rule:
def __init__(self, text, fn):
self.path = []
for r in text.split("/"):
r = r.strip()
l = r.split(" ")
self.path.append(l)
self.fn = fn
self.post = self.path[-1][0] == "*"
def match(self, path, text):
n = -1
args = []
for r in reversed(self.path):
if r[0] == "*":
args.append(text)
continue
if r[0] == "...":
args.append(path)
continue
if path[n][0] == r[0]:
for a in reversed(r[1:]):
try:
r = path[n][1][a]
except:
r = None
args.append(r)
n -= 1
else:
return
args.reverse()
self.fn(*args)
class GrulingXML(xml.sax.ContentHandler):
def __init__(self, rules, source):
self.rules = []
for rule in rules:
self.rules.append(Rule(*rule))
xml.sax.ContentHandler.__init__(self)
source = open(source)
self.path = []
self.content = ""
xml.sax.parse(source, self)
def startElement(self, name, attrs):
self.path.append([name, attrs])
self.content = ""
for rule in self.rules:
if not rule.post:
rule.match(self.path, self.content)
def endElement(self, name):
for rule in self.rules:
if rule.post:
rule.match(self.path, self.content)
self.path.pop()
pass
def characters(self, content):
self.content += content
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment