From c7febf61783c06f8fb68fa1ef26cc92d04ce2e98 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 27 Jan 2010 15:25:19 +0100 Subject: Improved the cldr parser for QLocale. I believe now we parse the CLDR properly. If a data is not present in a file, we remove the last part of the filename and try again. And we should do the same if a file is an alias to some other file. For example az_AZ.xml is an alias to az_Latn_AZ.xml which itself falls back to az_Latn.xml and then to az.xml Reviewed-by: Frans Englich --- util/local_database/cldr2qlocalexml.py | 286 +++++++++++++++++---------------- util/local_database/xpathlite.py | 113 +++++++++---- 2 files changed, 230 insertions(+), 169 deletions(-) diff --git a/util/local_database/cldr2qlocalexml.py b/util/local_database/cldr2qlocalexml.py index f837d94..6f4ee25 100755 --- a/util/local_database/cldr2qlocalexml.py +++ b/util/local_database/cldr2qlocalexml.py @@ -48,6 +48,7 @@ from xpathlite import DraftResolution import re findEntry = xpathlite.findEntry +findEntryInFile = xpathlite._findEntryInFile def ordStr(c): if len(c) == 1: @@ -73,13 +74,23 @@ def fixOrdStrList(c): def generateLocaleInfo(path): (dir_name, file_name) = os.path.split(path) - exp = re.compile(r"([a-z]+)_([A-Z]{2})\.xml") - m = exp.match(file_name) - if not m: + if not path.endswith(".xml"): + return {} + language_code = findEntryInFile(path, "identity/language", attribute="type")[0] + if language_code == 'root': + # just skip it + return {} + country_code = findEntryInFile(path, "identity/territory", attribute="type")[0] + script_code = findEntryInFile(path, "identity/script", attribute="type")[0] + variant_code = findEntryInFile(path, "identity/variant", attribute="type")[0] + + # we should handle fully qualified names with the territory + if not country_code: return {} - language_code = m.group(1) - country_code = m.group(2) + # we do not support scripts and variants + if variant_code or script_code: + return {} language_id = enumdata.languageCodeToId(language_code) if language_id == -1: @@ -93,179 +104,177 @@ def generateLocaleInfo(path): return {} country = enumdata.country_list[country_id][0] - base = dir_name + "/" + language_code + "_" + country_code - result = {} - result['base'] = base - result['language'] = language result['country'] = country + result['language_code'] = language_code + result['country_code'] = country_code result['language_id'] = language_id result['country_id'] = country_id - result['decimal'] = findEntry(base, "numbers/symbols/decimal") - result['group'] = findEntry(base, "numbers/symbols/group") - result['list'] = findEntry(base, "numbers/symbols/list") - result['percent'] = findEntry(base, "numbers/symbols/percentSign") - result['zero'] = findEntry(base, "numbers/symbols/nativeZeroDigit") - result['minus'] = findEntry(base, "numbers/symbols/minusSign") - result['plus'] = findEntry(base, "numbers/symbols/plusSign") - result['exp'] = findEntry(base, "numbers/symbols/exponential").lower() - result['am'] = findEntry(base, "dates/calendars/calendar[gregorian]/am", draft=DraftResolution.approved) - result['pm'] = findEntry(base, "dates/calendars/calendar[gregorian]/pm", draft=DraftResolution.approved) - result['longDateFormat'] = findEntry(base, "dates/calendars/calendar[gregorian]/dateFormats/dateFormatLength[full]/dateFormat/pattern") - result['shortDateFormat'] = findEntry(base, "dates/calendars/calendar[gregorian]/dateFormats/dateFormatLength[short]/dateFormat/pattern") - result['longTimeFormat'] = findEntry(base, "dates/calendars/calendar[gregorian]/timeFormats/timeFormatLength[full]/timeFormat/pattern") - result['shortTimeFormat'] = findEntry(base, "dates/calendars/calendar[gregorian]/timeFormats/timeFormatLength[short]/timeFormat/pattern") + result['decimal'] = findEntry(path, "numbers/symbols/decimal") + result['group'] = findEntry(path, "numbers/symbols/group") + result['list'] = findEntry(path, "numbers/symbols/list") + result['percent'] = findEntry(path, "numbers/symbols/percentSign") + result['zero'] = findEntry(path, "numbers/symbols/nativeZeroDigit") + result['minus'] = findEntry(path, "numbers/symbols/minusSign") + result['plus'] = findEntry(path, "numbers/symbols/plusSign") + result['exp'] = findEntry(path, "numbers/symbols/exponential").lower() + result['am'] = findEntry(path, "dates/calendars/calendar[gregorian]/am", draft=DraftResolution.approved) + result['pm'] = findEntry(path, "dates/calendars/calendar[gregorian]/pm", draft=DraftResolution.approved) + result['longDateFormat'] = findEntry(path, "dates/calendars/calendar[gregorian]/dateFormats/dateFormatLength[full]/dateFormat/pattern") + result['shortDateFormat'] = findEntry(path, "dates/calendars/calendar[gregorian]/dateFormats/dateFormatLength[short]/dateFormat/pattern") + result['longTimeFormat'] = findEntry(path, "dates/calendars/calendar[gregorian]/timeFormats/timeFormatLength[full]/timeFormat/pattern") + result['shortTimeFormat'] = findEntry(path, "dates/calendars/calendar[gregorian]/timeFormats/timeFormatLength[short]/timeFormat/pattern") standalone_long_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[stand-alone]/monthWidth[wide]/month" result['standaloneLongMonths'] \ - = findEntry(base, standalone_long_month_path + "[1]") + ";" \ - + findEntry(base, standalone_long_month_path + "[2]") + ";" \ - + findEntry(base, standalone_long_month_path + "[3]") + ";" \ - + findEntry(base, standalone_long_month_path + "[4]") + ";" \ - + findEntry(base, standalone_long_month_path + "[5]") + ";" \ - + findEntry(base, standalone_long_month_path + "[6]") + ";" \ - + findEntry(base, standalone_long_month_path + "[7]") + ";" \ - + findEntry(base, standalone_long_month_path + "[8]") + ";" \ - + findEntry(base, standalone_long_month_path + "[9]") + ";" \ - + findEntry(base, standalone_long_month_path + "[10]") + ";" \ - + findEntry(base, standalone_long_month_path + "[11]") + ";" \ - + findEntry(base, standalone_long_month_path + "[12]") + ";" + = findEntry(path, standalone_long_month_path + "[1]") + ";" \ + + findEntry(path, standalone_long_month_path + "[2]") + ";" \ + + findEntry(path, standalone_long_month_path + "[3]") + ";" \ + + findEntry(path, standalone_long_month_path + "[4]") + ";" \ + + findEntry(path, standalone_long_month_path + "[5]") + ";" \ + + findEntry(path, standalone_long_month_path + "[6]") + ";" \ + + findEntry(path, standalone_long_month_path + "[7]") + ";" \ + + findEntry(path, standalone_long_month_path + "[8]") + ";" \ + + findEntry(path, standalone_long_month_path + "[9]") + ";" \ + + findEntry(path, standalone_long_month_path + "[10]") + ";" \ + + findEntry(path, standalone_long_month_path + "[11]") + ";" \ + + findEntry(path, standalone_long_month_path + "[12]") + ";" standalone_short_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[stand-alone]/monthWidth[abbreviated]/month" result['standaloneShortMonths'] \ - = findEntry(base, standalone_short_month_path + "[1]") + ";" \ - + findEntry(base, standalone_short_month_path + "[2]") + ";" \ - + findEntry(base, standalone_short_month_path + "[3]") + ";" \ - + findEntry(base, standalone_short_month_path + "[4]") + ";" \ - + findEntry(base, standalone_short_month_path + "[5]") + ";" \ - + findEntry(base, standalone_short_month_path + "[6]") + ";" \ - + findEntry(base, standalone_short_month_path + "[7]") + ";" \ - + findEntry(base, standalone_short_month_path + "[8]") + ";" \ - + findEntry(base, standalone_short_month_path + "[9]") + ";" \ - + findEntry(base, standalone_short_month_path + "[10]") + ";" \ - + findEntry(base, standalone_short_month_path + "[11]") + ";" \ - + findEntry(base, standalone_short_month_path + "[12]") + ";" + = findEntry(path, standalone_short_month_path + "[1]") + ";" \ + + findEntry(path, standalone_short_month_path + "[2]") + ";" \ + + findEntry(path, standalone_short_month_path + "[3]") + ";" \ + + findEntry(path, standalone_short_month_path + "[4]") + ";" \ + + findEntry(path, standalone_short_month_path + "[5]") + ";" \ + + findEntry(path, standalone_short_month_path + "[6]") + ";" \ + + findEntry(path, standalone_short_month_path + "[7]") + ";" \ + + findEntry(path, standalone_short_month_path + "[8]") + ";" \ + + findEntry(path, standalone_short_month_path + "[9]") + ";" \ + + findEntry(path, standalone_short_month_path + "[10]") + ";" \ + + findEntry(path, standalone_short_month_path + "[11]") + ";" \ + + findEntry(path, standalone_short_month_path + "[12]") + ";" standalone_narrow_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[stand-alone]/monthWidth[narrow]/month" result['standaloneNarrowMonths'] \ - = findEntry(base, standalone_narrow_month_path + "[1]") + ";" \ - + findEntry(base, standalone_narrow_month_path + "[2]") + ";" \ - + findEntry(base, standalone_narrow_month_path + "[3]") + ";" \ - + findEntry(base, standalone_narrow_month_path + "[4]") + ";" \ - + findEntry(base, standalone_narrow_month_path + "[5]") + ";" \ - + findEntry(base, standalone_narrow_month_path + "[6]") + ";" \ - + findEntry(base, standalone_narrow_month_path + "[7]") + ";" \ - + findEntry(base, standalone_narrow_month_path + "[8]") + ";" \ - + findEntry(base, standalone_narrow_month_path + "[9]") + ";" \ - + findEntry(base, standalone_narrow_month_path + "[10]") + ";" \ - + findEntry(base, standalone_narrow_month_path + "[11]") + ";" \ - + findEntry(base, standalone_narrow_month_path + "[12]") + ";" + = findEntry(path, standalone_narrow_month_path + "[1]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[2]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[3]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[4]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[5]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[6]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[7]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[8]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[9]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[10]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[11]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[12]") + ";" long_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[format]/monthWidth[wide]/month" result['longMonths'] \ - = findEntry(base, long_month_path + "[1]") + ";" \ - + findEntry(base, long_month_path + "[2]") + ";" \ - + findEntry(base, long_month_path + "[3]") + ";" \ - + findEntry(base, long_month_path + "[4]") + ";" \ - + findEntry(base, long_month_path + "[5]") + ";" \ - + findEntry(base, long_month_path + "[6]") + ";" \ - + findEntry(base, long_month_path + "[7]") + ";" \ - + findEntry(base, long_month_path + "[8]") + ";" \ - + findEntry(base, long_month_path + "[9]") + ";" \ - + findEntry(base, long_month_path + "[10]") + ";" \ - + findEntry(base, long_month_path + "[11]") + ";" \ - + findEntry(base, long_month_path + "[12]") + ";" + = findEntry(path, long_month_path + "[1]") + ";" \ + + findEntry(path, long_month_path + "[2]") + ";" \ + + findEntry(path, long_month_path + "[3]") + ";" \ + + findEntry(path, long_month_path + "[4]") + ";" \ + + findEntry(path, long_month_path + "[5]") + ";" \ + + findEntry(path, long_month_path + "[6]") + ";" \ + + findEntry(path, long_month_path + "[7]") + ";" \ + + findEntry(path, long_month_path + "[8]") + ";" \ + + findEntry(path, long_month_path + "[9]") + ";" \ + + findEntry(path, long_month_path + "[10]") + ";" \ + + findEntry(path, long_month_path + "[11]") + ";" \ + + findEntry(path, long_month_path + "[12]") + ";" short_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[format]/monthWidth[abbreviated]/month" result['shortMonths'] \ - = findEntry(base, short_month_path + "[1]") + ";" \ - + findEntry(base, short_month_path + "[2]") + ";" \ - + findEntry(base, short_month_path + "[3]") + ";" \ - + findEntry(base, short_month_path + "[4]") + ";" \ - + findEntry(base, short_month_path + "[5]") + ";" \ - + findEntry(base, short_month_path + "[6]") + ";" \ - + findEntry(base, short_month_path + "[7]") + ";" \ - + findEntry(base, short_month_path + "[8]") + ";" \ - + findEntry(base, short_month_path + "[9]") + ";" \ - + findEntry(base, short_month_path + "[10]") + ";" \ - + findEntry(base, short_month_path + "[11]") + ";" \ - + findEntry(base, short_month_path + "[12]") + ";" + = findEntry(path, short_month_path + "[1]") + ";" \ + + findEntry(path, short_month_path + "[2]") + ";" \ + + findEntry(path, short_month_path + "[3]") + ";" \ + + findEntry(path, short_month_path + "[4]") + ";" \ + + findEntry(path, short_month_path + "[5]") + ";" \ + + findEntry(path, short_month_path + "[6]") + ";" \ + + findEntry(path, short_month_path + "[7]") + ";" \ + + findEntry(path, short_month_path + "[8]") + ";" \ + + findEntry(path, short_month_path + "[9]") + ";" \ + + findEntry(path, short_month_path + "[10]") + ";" \ + + findEntry(path, short_month_path + "[11]") + ";" \ + + findEntry(path, short_month_path + "[12]") + ";" narrow_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[format]/monthWidth[narrow]/month" result['narrowMonths'] \ - = findEntry(base, narrow_month_path + "[1]") + ";" \ - + findEntry(base, narrow_month_path + "[2]") + ";" \ - + findEntry(base, narrow_month_path + "[3]") + ";" \ - + findEntry(base, narrow_month_path + "[4]") + ";" \ - + findEntry(base, narrow_month_path + "[5]") + ";" \ - + findEntry(base, narrow_month_path + "[6]") + ";" \ - + findEntry(base, narrow_month_path + "[7]") + ";" \ - + findEntry(base, narrow_month_path + "[8]") + ";" \ - + findEntry(base, narrow_month_path + "[9]") + ";" \ - + findEntry(base, narrow_month_path + "[10]") + ";" \ - + findEntry(base, narrow_month_path + "[11]") + ";" \ - + findEntry(base, narrow_month_path + "[12]") + ";" + = findEntry(path, narrow_month_path + "[1]") + ";" \ + + findEntry(path, narrow_month_path + "[2]") + ";" \ + + findEntry(path, narrow_month_path + "[3]") + ";" \ + + findEntry(path, narrow_month_path + "[4]") + ";" \ + + findEntry(path, narrow_month_path + "[5]") + ";" \ + + findEntry(path, narrow_month_path + "[6]") + ";" \ + + findEntry(path, narrow_month_path + "[7]") + ";" \ + + findEntry(path, narrow_month_path + "[8]") + ";" \ + + findEntry(path, narrow_month_path + "[9]") + ";" \ + + findEntry(path, narrow_month_path + "[10]") + ";" \ + + findEntry(path, narrow_month_path + "[11]") + ";" \ + + findEntry(path, narrow_month_path + "[12]") + ";" long_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[format]/dayWidth[wide]/day" result['longDays'] \ - = findEntry(base, long_day_path + "[sun]") + ";" \ - + findEntry(base, long_day_path + "[mon]") + ";" \ - + findEntry(base, long_day_path + "[tue]") + ";" \ - + findEntry(base, long_day_path + "[wed]") + ";" \ - + findEntry(base, long_day_path + "[thu]") + ";" \ - + findEntry(base, long_day_path + "[fri]") + ";" \ - + findEntry(base, long_day_path + "[sat]") + ";" + = findEntry(path, long_day_path + "[sun]") + ";" \ + + findEntry(path, long_day_path + "[mon]") + ";" \ + + findEntry(path, long_day_path + "[tue]") + ";" \ + + findEntry(path, long_day_path + "[wed]") + ";" \ + + findEntry(path, long_day_path + "[thu]") + ";" \ + + findEntry(path, long_day_path + "[fri]") + ";" \ + + findEntry(path, long_day_path + "[sat]") + ";" short_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[format]/dayWidth[abbreviated]/day" result['shortDays'] \ - = findEntry(base, short_day_path + "[sun]") + ";" \ - + findEntry(base, short_day_path + "[mon]") + ";" \ - + findEntry(base, short_day_path + "[tue]") + ";" \ - + findEntry(base, short_day_path + "[wed]") + ";" \ - + findEntry(base, short_day_path + "[thu]") + ";" \ - + findEntry(base, short_day_path + "[fri]") + ";" \ - + findEntry(base, short_day_path + "[sat]") + ";" + = findEntry(path, short_day_path + "[sun]") + ";" \ + + findEntry(path, short_day_path + "[mon]") + ";" \ + + findEntry(path, short_day_path + "[tue]") + ";" \ + + findEntry(path, short_day_path + "[wed]") + ";" \ + + findEntry(path, short_day_path + "[thu]") + ";" \ + + findEntry(path, short_day_path + "[fri]") + ";" \ + + findEntry(path, short_day_path + "[sat]") + ";" narrow_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[format]/dayWidth[narrow]/day" result['narrowDays'] \ - = findEntry(base, narrow_day_path + "[sun]") + ";" \ - + findEntry(base, narrow_day_path + "[mon]") + ";" \ - + findEntry(base, narrow_day_path + "[tue]") + ";" \ - + findEntry(base, narrow_day_path + "[wed]") + ";" \ - + findEntry(base, narrow_day_path + "[thu]") + ";" \ - + findEntry(base, narrow_day_path + "[fri]") + ";" \ - + findEntry(base, narrow_day_path + "[sat]") + ";" + = findEntry(path, narrow_day_path + "[sun]") + ";" \ + + findEntry(path, narrow_day_path + "[mon]") + ";" \ + + findEntry(path, narrow_day_path + "[tue]") + ";" \ + + findEntry(path, narrow_day_path + "[wed]") + ";" \ + + findEntry(path, narrow_day_path + "[thu]") + ";" \ + + findEntry(path, narrow_day_path + "[fri]") + ";" \ + + findEntry(path, narrow_day_path + "[sat]") + ";" standalone_long_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[stand-alone]/dayWidth[wide]/day" result['standaloneLongDays'] \ - = findEntry(base, standalone_long_day_path + "[sun]") + ";" \ - + findEntry(base, standalone_long_day_path + "[mon]") + ";" \ - + findEntry(base, standalone_long_day_path + "[tue]") + ";" \ - + findEntry(base, standalone_long_day_path + "[wed]") + ";" \ - + findEntry(base, standalone_long_day_path + "[thu]") + ";" \ - + findEntry(base, standalone_long_day_path + "[fri]") + ";" \ - + findEntry(base, standalone_long_day_path + "[sat]") + ";" + = findEntry(path, standalone_long_day_path + "[sun]") + ";" \ + + findEntry(path, standalone_long_day_path + "[mon]") + ";" \ + + findEntry(path, standalone_long_day_path + "[tue]") + ";" \ + + findEntry(path, standalone_long_day_path + "[wed]") + ";" \ + + findEntry(path, standalone_long_day_path + "[thu]") + ";" \ + + findEntry(path, standalone_long_day_path + "[fri]") + ";" \ + + findEntry(path, standalone_long_day_path + "[sat]") + ";" standalone_short_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[stand-alone]/dayWidth[abbreviated]/day" result['standaloneShortDays'] \ - = findEntry(base, standalone_short_day_path + "[sun]") + ";" \ - + findEntry(base, standalone_short_day_path + "[mon]") + ";" \ - + findEntry(base, standalone_short_day_path + "[tue]") + ";" \ - + findEntry(base, standalone_short_day_path + "[wed]") + ";" \ - + findEntry(base, standalone_short_day_path + "[thu]") + ";" \ - + findEntry(base, standalone_short_day_path + "[fri]") + ";" \ - + findEntry(base, standalone_short_day_path + "[sat]") + ";" + = findEntry(path, standalone_short_day_path + "[sun]") + ";" \ + + findEntry(path, standalone_short_day_path + "[mon]") + ";" \ + + findEntry(path, standalone_short_day_path + "[tue]") + ";" \ + + findEntry(path, standalone_short_day_path + "[wed]") + ";" \ + + findEntry(path, standalone_short_day_path + "[thu]") + ";" \ + + findEntry(path, standalone_short_day_path + "[fri]") + ";" \ + + findEntry(path, standalone_short_day_path + "[sat]") + ";" standalone_narrow_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[stand-alone]/dayWidth[narrow]/day" result['standaloneNarrowDays'] \ - = findEntry(base, standalone_narrow_day_path + "[sun]") + ";" \ - + findEntry(base, standalone_narrow_day_path + "[mon]") + ";" \ - + findEntry(base, standalone_narrow_day_path + "[tue]") + ";" \ - + findEntry(base, standalone_narrow_day_path + "[wed]") + ";" \ - + findEntry(base, standalone_narrow_day_path + "[thu]") + ";" \ - + findEntry(base, standalone_narrow_day_path + "[fri]") + ";" \ - + findEntry(base, standalone_narrow_day_path + "[sat]") + ";" + = findEntry(path, standalone_narrow_day_path + "[sun]") + ";" \ + + findEntry(path, standalone_narrow_day_path + "[mon]") + ";" \ + + findEntry(path, standalone_narrow_day_path + "[tue]") + ";" \ + + findEntry(path, standalone_narrow_day_path + "[wed]") + ";" \ + + findEntry(path, standalone_narrow_day_path + "[thu]") + ";" \ + + findEntry(path, standalone_narrow_day_path + "[fri]") + ";" \ + + findEntry(path, standalone_narrow_day_path + "[sat]") + ";" return result @@ -465,9 +474,10 @@ for key in locale_keys: l = locale_database[key] print " " -# print " " + l['base'] + "" print " " + l['language'] + "" print " " + l['country'] + "" + print " " + l['language_code'] + "" + print " " + l['country_code'] + "" print " " + ordStr(l['decimal']) + "" print " " + ordStr(l['group']) + "" print " " + fixOrdStrList(l['list']) + "" diff --git a/util/local_database/xpathlite.py b/util/local_database/xpathlite.py index 7b5da5d..94bc23f 100644 --- a/util/local_database/xpathlite.py +++ b/util/local_database/xpathlite.py @@ -53,6 +53,11 @@ class DraftResolution: contributed = 'contributed' approved = 'approved' +class Error: + def __init__(self, msg): + self.msg = msg + def __str__(self): + return self.msg def findChild(parent, tag_name, arg_value, draft=None): for node in parent.childNodes: @@ -74,7 +79,7 @@ def findChild(parent, tag_name, arg_value, draft=None): return node return False -def _findEntry(file, path, draft=None): +def _findEntryInFile(file, path, draft=None, attribute=None): doc = False if doc_cache.has_key(file): doc = doc_cache[file] @@ -88,23 +93,47 @@ def _findEntry(file, path, draft=None): if draft is not None: last_entry = tag_spec_list[-1] tag_spec_list = tag_spec_list[:-1] - for tag_spec in tag_spec_list: + for i in range(len(tag_spec_list)): + tag_spec = tag_spec_list[i] tag_name = tag_spec arg_value = '' left_bracket = tag_spec.find('[') if left_bracket != -1: tag_name = tag_spec[:left_bracket] arg_value = tag_spec[left_bracket+1:-1] + alias = findChild(elt, 'alias', None) + if alias and alias.attributes['source'].nodeValue == 'locale': + path = alias.attributes['path'].nodeValue + aliaspath = tag_spec_list[:i] + path.split("/") + def resolve(x, y): + if y == '..': + return x[:-1] + return x + [y] + # resolve all dot-dot parts of the path + aliaspath = reduce(resolve, aliaspath, []) + # remove attribute specification that our xpathlite doesnt support + aliaspath = map(lambda x: x.replace("@type=", "").replace("'", ""), aliaspath) + # append the remaining path + aliaspath = aliaspath + tag_spec_list[i:] + aliaspath = "/".join(aliaspath) + # "locale" aliases are special - we need to start lookup from scratch + return (None, aliaspath) elt = findChild(elt, tag_name, arg_value) if not elt: - return "" + return ("", None) if last_entry is not None: elt = findChild(elt, last_entry, '', draft) if not elt: - return "" - return elt.firstChild.nodeValue + return ("", None) + if attribute is not None: + if elt.attributes.has_key(attribute): + return (elt.attributes[attribute].nodeValue, None) + return (None, None) + return (elt.firstChild.nodeValue, None) def findAlias(file): + if not doc_cache.has_key(file): + return False doc = doc_cache[file] alias_elt = findChild(doc.documentElement, "alias", "") if not alias_elt: @@ -113,37 +142,59 @@ def findAlias(file): return False return alias_elt.attributes['source'].nodeValue -def findEntry(base, path, draft=None): - file = base + ".xml" +def _findEntry(base, path, draft=None, attribute=None): + file = base + if base.endswith(".xml"): + file = base + base = base[:-4] + else: + file = base + ".xml" + (dirname, filename) = os.path.split(base) + items = filename.split("_") + # split locale name into items and iterate through them from back to front + # example: az_Latn_AZ => [az_Latn_AZ, az_Latn, az] + items = reversed(map(lambda x: "_".join(items[:x+1]), range(len(items)))) + for item in items: + file = dirname + "/" + item + ".xml" + if os.path.isfile(file): + alias = findAlias(file) + if alias: + # if alias is found we should follow it and stop processing current file + # see http://www.unicode.org/reports/tr35/#Common_Elements + aliasfile = os.path.dirname(file) + "/" + alias + ".xml" + if not os.path.isfile(aliasfile): + raise Error("findEntry: fatal error: found an alias '%s' to '%s', but the alias file couldnt be found" % (filename, alias)) + # found an alias, recurse into parsing it + result = _findEntry(aliasfile, path, draft, attribute) + return result + (result, aliaspath) = _findEntryInFile(file, path, draft, attribute) + if aliaspath: + # start lookup again because of the alias source="locale" + return _findEntry(base, aliaspath, draft, attribute) + if result: + return result + return None + +def findEntry(base, path, draft=None, attribute=None): + file = base + if base.endswith(".xml"): + file = base + base = base[:-4] + else: + file = base + ".xml" + (dirname, filename) = os.path.split(base) - if os.path.isfile(file): - result = _findEntry(file, path, draft) + result = None + while path: + result = _findEntry(base, path, draft, attribute) if result: return result - - alias = findAlias(file) - if alias: - file = os.path.dirname(base) + "/" + alias + ".xml" - if os.path.isfile(file): - result = _findEntry(file, path, draft) - if result: - return result - - file = base[:-3] + ".xml" - if os.path.isfile(file): - result = _findEntry(file, path, draft) + (result, aliaspath) = _findEntryInFile(dirname + "/root.xml", path, draft, attribute) if result: return result - alias = findAlias(file) - if alias: - file = os.path.dirname(base) + "/" + alias + ".xml" - if os.path.isfile(file): - result = _findEntry(file, path, draft) - if result: - return result + if not aliaspath: + raise Error("findEntry: fatal error: %s: did not found key %s" % (filename, path)) + path = aliaspath - if not draft: - file = os.path.dirname(base) + "/root.xml" - result = _findEntry(file, path, draft) return result -- cgit v0.12