"""
Checks schema for files matching certain file names using either
lxml or SAX2Count.exe depending on availability.
"""
from __future__ import absolute_import
from __future__ import print_function
import os
import sys
import subprocess
import glob
import traceback
try:
from urllib.request import unquote
except ImportError:
from urllib import unquote
try:
from lxml import etree
haveLxml = True
schemes = {}
except ImportError:
haveLxml = False
def validate(root, f):
root = os.path.abspath(root)
normalized = os.path.abspath(f)[len(root) + 1:].replace('\\', '/')
try:
if os.path.getsize(f) < 80:
return
doc = etree.parse(f)
schemaLoc = doc.getroot().get(
'{http://www.w3.org/2001/XMLSchema-instance}noNamespaceSchemaLocation')
if schemaLoc and '/xsd/' in schemaLoc:
localSchema = os.path.join(os.path.dirname(
__file__), '..', '..', 'data', schemaLoc[schemaLoc.find('/xsd/') + 1:])
if os.path.exists(localSchema):
schemaLoc = localSchema
schemes[schemaLoc] = etree.XMLSchema(etree.parse(schemaLoc))
schemes[schemaLoc].validate(doc)
for entry in schemes[schemaLoc].error_log:
s = unquote(str(entry))
s = s[s.find(f.replace('\\', '/')) + len(f):]
print(normalized + s, file=sys.stderr)
except Exception as e:
print("Error on parsing '%s'!" % normalized, file=sys.stderr)
if haveLxml and type(e) is etree.XMLSyntaxError:
print(e, file=sys.stderr)
else:
traceback.print_exc()
def main(srcRoot, toCheck, err):
if not toCheck:
toCheck = ["*.edg.xml", "*.nod.xml", "*.con.xml", "*.typ.xml",
"*.net.xml", "*.rou.xml", "*.add.xml", "*.????cfg",
"net.netgen", "net.netconvert",
"net.scenario", "tls.scenario",
"routes.duarouter", "alts.duarouter", "routes.jtrrouter", "routes.marouter",
"vehroutes.sumo", "vehroutes.sumo.meso", "trips.od2trips",
"*.turns.xml"]
sax2count = "SAX2Count.exe"
if 'XERCES_64' in os.environ:
sax2count = os.path.join(os.environ['XERCES_64'], "bin", sax2count)
elif 'XERCES' in os.environ:
sax2count = os.path.join(os.environ['XERCES'], "bin", sax2count)
fileNo = 0
if os.path.exists(srcRoot):
if os.path.isdir(srcRoot):
for root, dirs, _ in os.walk(srcRoot):
for pattern in toCheck:
for name in glob.glob(os.path.join(root, pattern)):
if haveLxml:
validate(srcRoot, name)
elif os.name != "posix":
subprocess.call(sax2count + " " + name, stdout=open(os.devnull), stderr=err)
fileNo += 1
if '.svn' in dirs:
dirs.remove('.svn')
else:
if haveLxml:
validate("", srcRoot)
elif os.name != "posix":
subprocess.call(
sax2count + " " + srcRoot, stdout=open(os.devnull), stderr=err)
fileNo += 1
else:
print("cannot open", srcRoot, file=err)
return 1
print("%s files checked" % fileNo)
return 0
if __name__ == "__main__":
if os.name == "posix" and not haveLxml:
print("neither SAX2Count nor lxml available, exiting", file=sys.stderr)
sys.exit(1)
srcRoot = "."
if len(sys.argv) > 1:
srcRoot = sys.argv[1]
if "$SUMO_HOME" in srcRoot:
srcRoot = srcRoot.replace("$SUMO_HOME",
os.path.join(os.path.dirname(__file__), '..', '..'))
toCheck = None
if len(sys.argv) > 2:
toCheck = sys.argv[2].split(",")
sys.exit(main(srcRoot, toCheck, sys.stderr))