##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""XML Locale-related objects and functions
$Id: xmlfactory.py 30750 2005-06-10 23:57:01Z philikon $
"""
from datetime import datetime, date, time
from xml.dom.minidom import parse as parseXML
from zope.i18n.locales import Locale, LocaleDisplayNames, LocaleDates
from zope.i18n.locales import LocaleVersion, LocaleIdentity, LocaleTimeZone
from zope.i18n.locales import LocaleCalendar, LocaleCurrency, LocaleNumbers
from zope.i18n.locales import LocaleFormat, LocaleFormatLength, dayMapping
from zope.i18n.locales import LocaleOrientation
from zope.i18n.locales.inheritance import InheritingDictionary
class LocaleFactory(object):
"""This class creates a Locale object from an ICU XML file."""
def __init__(self, path):
"""Initialize factory."""
self._path = path
# Mainly for testing
if path:
self._data = parseXML(path).documentElement
def _getText(self, nodelist):
rc = u''
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc = rc + node.data
return rc
def _extractVersion(self, identity_node):
"""Extract the Locale's version info based on data from the DOM
tree.
Example::
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
... Some notes
...
...
...
... '''
>>> dom = parseString(xml)
>>> version = factory._extractVersion(dom.documentElement)
>>> version.number
u'1.0'
>>> version.generationDate
datetime.date(2003, 12, 19)
>>> version.notes
u'Some notes'
"""
number = generationDate = notes = None
# Retrieve the version number and notes of the locale
nodes = identity_node.getElementsByTagName('version')
if nodes:
number = nodes[0].getAttribute('number')
notes = self._getText(nodes[0].childNodes)
# Retrieve the generationDate of the locale
nodes = identity_node.getElementsByTagName('generation')
if nodes:
year, month, day = nodes[0].getAttribute('date').split('-')
generationDate = date(int(year), int(month), int(day))
return LocaleVersion(number, generationDate, notes)
def _extractIdentity(self):
"""Extract the Locale's identity object based on info from the DOM
tree.
Example::
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
...
...
...
...
...
...
... '''
>>> factory = LocaleFactory(None)
>>> factory._data = parseString(xml).documentElement
>>> id = factory._extractIdentity()
>>> id.language
u'en'
>>> id.script is None
True
>>> id.territory
u'US'
>>> id.variant
u'POSIX'
>>> id.version.number
u'1.0'
"""
id = LocaleIdentity()
identity = self._data.getElementsByTagName('identity')[0]
# Retrieve the language of the locale
nodes = identity.getElementsByTagName('language')
if nodes != []:
id.language = nodes[0].getAttribute('type') or None
# Retrieve the territory of the locale
nodes = identity.getElementsByTagName('territory')
if nodes != []:
id.territory = nodes[0].getAttribute('type') or None
# Retrieve the varriant of the locale
nodes = identity.getElementsByTagName('variant')
if nodes != []:
id.variant = nodes[0].getAttribute('type') or None
id.version = self._extractVersion(identity)
return id
def _extractTypes(self, names_node):
"""Extract all types from the names_node.
Example::
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
...
... BUDDHIST
... CHINESE
... GREGORIAN
... STROKE
... TRADITIONAL
...
... '''
>>> dom = parseString(xml)
>>> types = factory._extractTypes(dom.documentElement)
>>> keys = types.keys()
>>> keys.sort()
>>> keys[:2]
[(u'Fallback', u'calendar'), (u'buddhist', u'calendar')]
>>> keys[2:4]
[(u'chinese', u'calendar'), (u'gregorian', u'calendar')]
>>> keys[4:]
[(u'stroke', u'collation'), (u'traditional', u'collation')]
>>> types[(u'chinese', u'calendar')]
u'CHINESE'
>>> types[(u'stroke', u'collation')]
u'STROKE'
"""
# 'types' node has not to exist
types_nodes = names_node.getElementsByTagName('types')
if types_nodes == []:
return
# Retrieve all types
types = InheritingDictionary()
for type_node in types_nodes[0].getElementsByTagName('type'):
type = type_node.getAttribute('type')
key = type_node.getAttribute('key')
types[(type, key)] = self._getText(type_node.childNodes)
return types
def _extractDisplayNames(self):
"""Extract all display names from the DOM tree.
Example::
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
...
...
... aa
... ab
...
...
...
...
...
...
... AD
... AE
...
...
...
... POSIX
...
...
... CALENDAR
... COLLATION
...
...
... BUDDHIST
... STROKE
...
...
... '''
>>> factory = LocaleFactory(None)
>>> factory._data = parseString(xml).documentElement
>>> names = factory._extractDisplayNames()
>>> keys = names.languages.keys()
>>> keys.sort()
>>> keys
[u'Fallback', u'aa', u'ab']
>>> names.languages[u'aa']
u'aa'
>>> keys = names.scripts.keys()
>>> keys.sort()
>>> keys
[u'Arab', u'Armn']
>>> names.scripts[u'Arab']
u'Arab'
>>> keys = names.territories.keys()
>>> keys.sort()
>>> keys
[u'AD', u'AE']
>>> names.territories[u'AD']
u'AD'
>>> keys = names.variants.keys()
>>> keys.sort()
>>> keys
[u'Fallback', u'POSIX']
>>> names.variants[u'Fallback']
u''
>>> keys = names.keys.keys()
>>> keys.sort()
>>> keys
[u'calendar', u'collation']
>>> names.keys[u'calendar']
u'CALENDAR'
>>> names.types[(u'stroke', u'collation')]
u'STROKE'
"""
displayNames = LocaleDisplayNames()
# Neither the 'localeDisplayNames' or 'scripts' node has to exist
names_nodes = self._data.getElementsByTagName('localeDisplayNames')
if names_nodes == []:
return displayNames
for group_tag, single_tag in (('languages', 'language'),
('scripts', 'script'),
('territories', 'territory'),
('variants', 'variant'),
('keys', 'key')):
group_nodes = names_nodes[0].getElementsByTagName(group_tag)
if group_nodes == []:
continue
# Retrieve all children
elements = InheritingDictionary()
for element in group_nodes[0].getElementsByTagName(single_tag):
type = element.getAttribute('type')
elements[type] = self._getText(element.childNodes)
setattr(displayNames, group_tag, elements)
types = self._extractTypes(names_nodes[0])
if types is not None:
displayNames.types = types
return displayNames
def _extractMonths(self, cal_node, calendar):
"""Extract all month entries from cal_node and store them in calendar.
Example::
>>> class CalendarStub(object):
... months = None
>>> calendar = CalendarStub()
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
... Januar
... Februar
... Maerz
... April
... Mai
... Juni
... Juli
... August
... September
... Oktober
... November
... Dezember
...
...
... Jan
... Feb
... Mrz
... Apr
... Mai
... Jun
... Jul
... Aug
... Sep
... Okt
... Nov
... Dez
...
... '''
>>> dom = parseString(xml)
>>> factory._extractMonths(dom.documentElement, calendar)
>>> names = [calendar.months.get(type, (None, None))[0]
... for type in range(1, 13)]
>>> names[:7]
[u'Januar', u'Februar', u'Maerz', u'April', u'Mai', u'Juni', u'Juli']
>>> names[7:]
[u'August', u'September', u'Oktober', u'November', u'Dezember']
>>> abbrs = [calendar.months.get(type, (None, None))[1]
... for type in range(1, 13)]
>>> abbrs[:6]
[u'Jan', u'Feb', u'Mrz', u'Apr', u'Mai', u'Jun']
>>> abbrs[6:]
[u'Jul', u'Aug', u'Sep', u'Okt', u'Nov', u'Dez']
"""
# See whether we have month names and abbreviations
names_nodes = cal_node.getElementsByTagName('monthNames')
abbrs_nodes = cal_node.getElementsByTagName('monthAbbr')
if not (names_nodes and abbrs_nodes):
return
# Get all month names
names = {}
for name_node in names_nodes[0].getElementsByTagName('month'):
type = int(name_node.getAttribute('type'))
names[type] = self._getText(name_node.childNodes)
# Get all month abbrs
abbrs = {}
for abbr_node in abbrs_nodes[0].getElementsByTagName('month'):
type = int(abbr_node.getAttribute('type'))
abbrs[type] = self._getText(abbr_node.childNodes)
# Put the info together
calendar.months = InheritingDictionary()
for type in range(1, 13):
calendar.months[type] = (names.get(type, None),
abbrs.get(type, None))
def _extractDays(self, cal_node, calendar):
"""Extract all day entries from cal_node and store them in
calendar.
Example::
>>> class CalendarStub(object):
... days = None
>>> calendar = CalendarStub()
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
... Sonntag
... Montag
... Dienstag
... Mittwoch
... Donnerstag
... Freitag
... Samstag
...
...
... So
... Mo
... Di
... Mi
... Do
... Fr
... Sa
...
... '''
>>> dom = parseString(xml)
>>> factory._extractDays(dom.documentElement, calendar)
>>> names = [calendar.days.get(type, (None, None))[0]
... for type in range(1, 8)]
>>> names[:4]
[u'Montag', u'Dienstag', u'Mittwoch', u'Donnerstag']
>>> names[4:]
[u'Freitag', u'Samstag', u'Sonntag']
>>> abbrs = [calendar.days.get(type, (None, None))[1]
... for type in range(1, 8)]
>>> abbrs
[u'Mo', u'Di', u'Mi', u'Do', u'Fr', u'Sa', u'So']
"""
# See whether we have weekday names and abbreviations
names_nodes = cal_node.getElementsByTagName('dayNames')
abbrs_nodes = cal_node.getElementsByTagName('dayAbbr')
if not (names_nodes and abbrs_nodes):
return
# Get all weekday names
names = {}
for name_node in names_nodes[0].getElementsByTagName('day'):
type = dayMapping[name_node.getAttribute('type')]
names[type] = self._getText(name_node.childNodes)
# Get all weekday abbreviations
abbrs = {}
for abbr_node in abbrs_nodes[0].getElementsByTagName('day'):
type = dayMapping[abbr_node.getAttribute('type')]
abbrs[type] = self._getText(abbr_node.childNodes)
# Put the info together
calendar.days = InheritingDictionary()
for type in range(1, 13):
calendar.days[type] = (names.get(type, None),
abbrs.get(type, None))
def _extractWeek(self, cal_node, calendar):
"""Extract all week entries from cal_node and store them in
calendar.
Example::
>>> class CalendarStub(object):
... week = None
>>> calendar = CalendarStub()
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
...
...
...
...
...
... '''
>>> dom = parseString(xml)
>>> factory._extractWeek(dom.documentElement, calendar)
>>> calendar.week['minDays']
1
>>> calendar.week['firstDay']
7
>>> calendar.week['weekendStart']
(5, datetime.time(18, 0))
>>> calendar.week['weekendEnd']
(7, datetime.time(18, 0))
"""
# See whether we have week entries
week_nodes = cal_node.getElementsByTagName('week')
if not week_nodes:
return
calendar.week = InheritingDictionary()
# Get the 'minDays' value if available
for node in week_nodes[0].getElementsByTagName('minDays'):
calendar.week['minDays'] = int(node.getAttribute('count'))
# Get the 'firstDay' value if available
for node in week_nodes[0].getElementsByTagName('firstDay'):
calendar.week['firstDay'] = dayMapping[node.getAttribute('day')]
# Get the 'weekendStart' value if available
for node in week_nodes[0].getElementsByTagName('weekendStart'):
day = dayMapping[node.getAttribute('day')]
time_args = map(int, node.getAttribute('time').split(':'))
calendar.week['weekendStart'] = (day, time(*time_args))
# Get the 'weekendEnd' value if available
for node in week_nodes[0].getElementsByTagName('weekendEnd'):
day = dayMapping[node.getAttribute('day')]
time_args = map(int, node.getAttribute('time').split(':'))
calendar.week['weekendEnd'] = (day, time(*time_args))
def _extractEras(self, cal_node, calendar):
"""Extract all era entries from cal_node and store them in
calendar.
Example::
>>> class CalendarStub(object):
... days = None
>>> calendar = CalendarStub()
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
...
... BC
... AD
...
...
... Before Christ
...
...
... '''
>>> dom = parseString(xml)
>>> factory._extractEras(dom.documentElement, calendar)
>>> names = [calendar.eras.get(type, (None, None))[0]
... for type in range(2)]
>>> names
[u'Before Christ', None]
>>> abbrs = [calendar.eras.get(type, (None, None))[1]
... for type in range(2)]
>>> abbrs
[u'BC', u'AD']
"""
# See whether we have era names and abbreviations
eras_nodes = cal_node.getElementsByTagName('eras')
if not eras_nodes:
return
names_nodes = eras_nodes[0].getElementsByTagName('eraName')
abbrs_nodes = eras_nodes[0].getElementsByTagName('eraAbbr')
# Get all era names
names = {}
if names_nodes:
for name_node in names_nodes[0].getElementsByTagName('era'):
type = int(name_node.getAttribute('type'))
names[type] = self._getText(name_node.childNodes)
# Get all era abbreviations
abbrs = {}
if abbrs_nodes:
for abbr_node in abbrs_nodes[0].getElementsByTagName('era'):
type = int(abbr_node.getAttribute('type'))
abbrs[type] = self._getText(abbr_node.childNodes)
calendar.eras = InheritingDictionary()
for type in abbrs.keys():
calendar.eras[type] = (names.get(type, None), abbrs.get(type, None))
def _extractFormats(self, formats_node, lengthNodeName, formatNodeName):
"""Extract all format entries from formats_node and return a
tuple of the form (defaultFormatType, [LocaleFormatLength, ...]).
Example::
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
...
...
... EEEE, MMMM d, yyyy
...
...
...
...
...
... Standard Date
... MMM d, yyyy
...
...
... MMM dd, yyyy
...
...
... '''
>>> dom = parseString(xml)
>>> default, lengths = factory._extractFormats(
... dom.documentElement, 'dateFormatLength', 'dateFormat')
>>> default
u'medium'
>>> lengths[u'full'].formats[None].pattern
u'EEEE, MMMM d, yyyy'
>>> lengths[u'medium'].default
u'DateFormatsKey2'
>>> lengths[u'medium'].formats['DateFormatsKey3'].pattern
u'MMM dd, yyyy'
>>> lengths[u'medium'].formats['DateFormatsKey2'].displayName
u'Standard Date'
"""
formats_default = None
default_nodes = formats_node.getElementsByTagName('default')
if default_nodes:
formats_default = default_nodes[0].getAttribute('type')
lengths = InheritingDictionary()
for length_node in formats_node.getElementsByTagName(lengthNodeName):
type = length_node.getAttribute('type') or None
length = LocaleFormatLength(type)
default_nodes = length_node.getElementsByTagName('default')
if default_nodes:
length.default = default_nodes[0].getAttribute('type')
if length_node.getElementsByTagName(formatNodeName):
length.formats = InheritingDictionary()
for format_node in length_node.getElementsByTagName(formatNodeName):
format = LocaleFormat()
format.type = format_node.getAttribute('type') or None
pattern_node = format_node.getElementsByTagName('pattern')[0]
format.pattern = self._getText(pattern_node.childNodes)
name_nodes = format_node.getElementsByTagName('displayName')
if name_nodes:
format.displayName = self._getText(name_nodes[0].childNodes)
length.formats[format.type] = format
lengths[length.type] = length
return (formats_default, lengths)
def _extractCalendars(self, dates_node):
"""Extract all calendars and their specific information from the
Locale's DOM tree.
Example::
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
...
...
... January
... December
...
...
... Jan
... Dec
...
...
... Sunday
... Saturday
...
...
... Sun
... Sat
...
...
...
...
...
... AM
... PM
...
...
... BC
... AD
...
...
...
...
...
... EEEE, MMMM d, yyyy
...
...
...
...
...
...
...
... h:mm:ss a
...
...
...
...
...
...
... {0} {1}
...
...
...
...
...
...
... BE
...
...
...
... '''
>>> dom = parseString(xml)
>>> calendars = factory._extractCalendars(dom.documentElement)
>>> keys = calendars.keys()
>>> keys.sort()
>>> keys
[u'gregorian', u'thai-buddhist']
"""
cals_nodes = dates_node.getElementsByTagName('calendars')
# no calendar node
if cals_nodes == []:
return
calendars = InheritingDictionary()
for cal_node in cals_nodes[0].getElementsByTagName('calendar'):
# get the calendar type
type = cal_node.getAttribute('type')
calendar = LocaleCalendar(type)
# get month names and abbreviations
self._extractMonths(cal_node, calendar)
# get weekday names and abbreviations
self._extractDays(cal_node, calendar)
# get week information
self._extractWeek(cal_node, calendar)
# get am/pm designation values
nodes = cal_node.getElementsByTagName('am')
if nodes:
calendar.am = self._getText(nodes[0].childNodes)
nodes = cal_node.getElementsByTagName('pm')
if nodes:
calendar.pm = self._getText(nodes[0].childNodes)
# get era names and abbreviations
self._extractEras(cal_node, calendar)
for formatsName, lengthName, formatName in (
('dateFormats', 'dateFormatLength', 'dateFormat'),
('timeFormats', 'timeFormatLength', 'timeFormat'),
('dateTimeFormats', 'dateTimeFormatLength', 'dateTimeFormat')):
formats_nodes = cal_node.getElementsByTagName(formatsName)
if formats_nodes:
default, formats = self._extractFormats(
formats_nodes[0], lengthName, formatName)
setattr(calendar,
'default'+formatName[0].upper()+formatName[1:],
default)
setattr(calendar, formatsName, formats)
calendars[calendar.type] = calendar
return calendars
def _extractTimeZones(self, dates_node):
"""Extract all timezone information for the locale from the DOM
tree.
Example::
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
...
...
... Pacific Time
... Pacific Standard Time
... Pacific Daylight Time
...
...
... PT
... PST
... PDT
...
... San Francisco
...
...
...
... British Time
... British Standard Time
... British Daylight Time
...
... York
...
...
... '''
>>> dom = parseString(xml)
>>> zones = factory._extractTimeZones(dom.documentElement)
>>> keys = zones.keys()
>>> keys.sort()
>>> keys
[u'America/Los_Angeles', u'Europe/London']
>>> zones[u'Europe/London'].names[u'generic']
(u'British Time', None)
>>> zones[u'Europe/London'].cities
[u'York']
>>> zones[u'America/Los_Angeles'].names[u'generic']
(u'Pacific Time', u'PT')
"""
tz_names = dates_node.getElementsByTagName('timeZoneNames')
if not tz_names:
return
zones = InheritingDictionary()
for node in tz_names[0].getElementsByTagName('zone'):
type = node.getAttribute('type')
zone = LocaleTimeZone(type)
# get the short and long name node
long = node.getElementsByTagName('long')
short = node.getElementsByTagName('short')
for type in (u'generic', u'standard', u'daylight'):
# get long name
long_desc = None
if long:
long_nodes = long[0].getElementsByTagName(type)
if long_nodes:
long_desc = self._getText(long_nodes[0].childNodes)
# get short name
short_desc = None
if short:
short_nodes = short[0].getElementsByTagName(type)
if short_nodes:
short_desc = self._getText(short_nodes[0].childNodes)
if long_desc is not None or short_desc is not None:
zone.names[type] = (long_desc, short_desc)
for city in node.getElementsByTagName('exemplarCity'):
zone.cities.append(self._getText(city.childNodes))
zones[zone.type] = zone
return zones
def _extractDates(self):
"""Extract all date information from the DOM tree"""
dates_nodes = self._data.getElementsByTagName('dates')
if dates_nodes == []:
return
dates = LocaleDates()
calendars = self._extractCalendars(dates_nodes[0])
if calendars is not None:
dates.calendars = calendars
timezones = self._extractTimeZones(dates_nodes[0])
if timezones is not None:
dates.timezones = timezones
return dates
def _extractSymbols(self, numbers_node):
"""Extract all week entries from cal_node and store them in
calendar.
Example::
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
... .
... ,
... ;
... %
... 0
... #
... +
... -
... E
... o/oo
... oo
... NaN
...
... '''
>>> dom = parseString(xml)
>>> symbols = factory._extractSymbols(dom.documentElement)
>>> symbols['list']
u';'
>>> keys = symbols.keys()
>>> keys.sort()
>>> keys[:5]
[u'decimal', u'exponential', u'group', u'infinity', u'list']
>>> keys[5:9]
[u'minusSign', u'nan', u'nativeZeroDigit', u'patternDigit']
>>> keys[9:]
[u'perMille', u'percentSign', u'plusSign']
"""
# See whether we have symbols entries
symbols_nodes = numbers_node.getElementsByTagName('symbols')
if not symbols_nodes:
return
symbols = InheritingDictionary()
for name in (u'decimal', u'group', u'list', u'percentSign',
u'nativeZeroDigit', u'patternDigit', u'plusSign',
u'minusSign', u'exponential', u'perMille',
u'infinity', u'nan'):
nodes = symbols_nodes[0].getElementsByTagName(name)
if nodes:
symbols[name] = self._getText(nodes[0].childNodes)
return symbols
def _extractNumberFormats(self, numbers_node, numbers):
"""Extract all number formats from the numbers_node and save the data
in numbers.
Example::
>>> class Numbers(object):
... defaultDecimalFormat = None
... decimalFormats = None
... defaultScientificFormat = None
... scientificFormats = None
... defaultPercentFormat = None
... percentFormats = None
... defaultCurrencyFormat = None
... currencyFormats = None
>>> numbers = Numbers()
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
...
...
... #,##0.###
...
...
...
...
...
...
...
... 0.000###E+00
...
...
...
...
... 0.00##E+00
...
...
...
...
...
...
... #,##0%
...
...
...
...
...
...
... $ #,##0.00;($ #,##0.00)
...
...
...
... '''
>>> dom = parseString(xml)
>>> factory._extractNumberFormats(dom.documentElement, numbers)
>>> numbers.decimalFormats[u'long'].formats[None].pattern
u'#,##0.###'
>>> numbers.defaultScientificFormat
u'long'
>>> numbers.scientificFormats[u'long'].formats[None].pattern
u'0.000###E+00'
>>> numbers.scientificFormats[u'medium'].formats[None].pattern
u'0.00##E+00'
>>> numbers.percentFormats[u'long'].formats[None].pattern
u'#,##0%'
>>> numbers.percentFormats.get(u'medium', None) is None
True
>>> numbers.currencyFormats[u'long'].formats[None].pattern
u'$ #,##0.00;($ #,##0.00)'
>>> numbers.currencyFormats.get(u'medium', None) is None
True
"""
for category in ('decimal', 'scientific', 'percent', 'currency'):
formatsName = category+'Formats'
lengthName = category+'FormatLength'
formatName = category+'Format'
defaultName = 'default'+formatName[0].upper()+formatName[1:]
formats_nodes = numbers_node.getElementsByTagName(formatsName)
if formats_nodes:
default, formats = self._extractFormats(
formats_nodes[0], lengthName, formatName)
setattr(numbers, defaultName, default)
setattr(numbers, formatsName, formats)
def _extractCurrencies(self, numbers_node):
"""Extract all currency definitions and their information from the
Locale's DOM tree.
Example::
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
...
... Dollar
... $
...
...
... Yen
... Y
...
...
... Rupee
... 0<=Rf|1<=Ru|1<Rf
...
...
... Escudo
... $
...
...
... '''
>>> dom = parseString(xml)
>>> currencies = factory._extractCurrencies(dom.documentElement)
>>> keys = currencies.keys()
>>> keys.sort()
>>> keys
[u'INR', u'JPY', u'PTE', u'USD']
>>> currencies['USD'].symbol
u'$'
>>> currencies['USD'].displayName
u'Dollar'
>>> currencies['USD'].symbolChoice
False
"""
currs_nodes = numbers_node.getElementsByTagName('currencies')
if not currs_nodes:
return
currencies = InheritingDictionary()
for curr_node in currs_nodes[0].getElementsByTagName('currency'):
type = curr_node.getAttribute('type')
currency = LocaleCurrency(type)
nodes = curr_node.getElementsByTagName('symbol')
if nodes:
currency.symbol = self._getText(nodes[0].childNodes)
currency.symbolChoice = \
nodes[0].getAttribute('choice') == u'true'
nodes = curr_node.getElementsByTagName('displayName')
if nodes:
currency.displayName = self._getText(nodes[0].childNodes)
currencies[type] = currency
return currencies
def _extractNumbers(self):
"""Extract all number information from the DOM tree"""
numbers_nodes = self._data.getElementsByTagName('numbers')
if not numbers_nodes:
return
numbers = LocaleNumbers()
symbols = self._extractSymbols(numbers_nodes[0])
if symbols is not None:
numbers.symbols = symbols
self._extractNumberFormats(numbers_nodes[0], numbers)
currencies = self._extractCurrencies(numbers_nodes[0])
if currencies is not None:
numbers.currencies = currencies
return numbers
def _extractDelimiters(self):
"""Extract all delimiter entries from the DOM tree.
Example::
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
... ``
... ''
... `
... '
...
... '''
>>> dom = parseString(xml)
>>> factory._data = parseString(xml).documentElement
>>> delimiters = factory._extractDelimiters()
>>> delimiters[u'quotationStart']
u'``'
>>> delimiters[u'quotationEnd']
u"''"
>>> delimiters[u'alternateQuotationStart']
u'`'
>>> delimiters[u'alternateQuotationEnd']
u"'"
Escape: "'"
"""
# See whether we have symbols entries
delimiters_nodes = self._data.getElementsByTagName('delimiters')
if not delimiters_nodes:
return
delimiters = InheritingDictionary()
for name in (u'quotationStart', u'quotationEnd',
u'alternateQuotationStart', u'alternateQuotationEnd'):
nodes = delimiters_nodes[0].getElementsByTagName(name)
if nodes:
delimiters[name] = self._getText(nodes[0].childNodes)
return delimiters
def _extractOrientation(self):
"""Extract orientation information.
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
>>> xml = u'''
...
...
...
...
... '''
>>> dom = parseString(xml)
>>> factory._data = parseString(xml).documentElement
>>> orientation = factory._extractOrientation()
>>> orientation.lines
u'bottom-to-top'
>>> orientation.characters
u'right-to-left'
"""
orientation_nodes = self._data.getElementsByTagName('orientation')
if not orientation_nodes:
return
orientation = LocaleOrientation()
for name in (u'characters', u'lines'):
value = orientation_nodes[0].getAttribute(name)
if value:
setattr(orientation, name, value)
return orientation
def __call__(self):
"""Create the Locale."""
locale = Locale(self._extractIdentity())
names = self._extractDisplayNames()
if names is not None:
locale.displayNames = names
dates = self._extractDates()
if dates is not None:
locale.dates = dates
numbers = self._extractNumbers()
if numbers is not None:
locale.numbers = numbers
delimiters = self._extractDelimiters()
if delimiters is not None:
locale.delimiters = delimiters
orientation = self._extractOrientation()
if orientation is not None:
locale.orientation = orientation
# Unmapped:
#
# -
# -
# - ,
return locale