Commits

Martin von Löwis  committed 861771d

Support dictionary elements.

  • Participants
  • Parent commits f5a039b

Comments (0)

Files changed (1)

File cldr/ldml.py

     def initialvalue(self):
         return []
 
+class LDMLSingleKey(dict):
+    '''Dictionary keyed with a single key, either specified using standard dict lookup
+    or as a keyword argument to get'''
+    def __init__(self, key):
+        self.key = key
+
+    def get(self, *args, **kw):
+        if len(args) == 1:
+            return super().get(args[0])
+        if len(kw) == 1:
+            return super().get(kw[self.key])
+        return super().get(*args, **kw)
+
+class LDMLMultipleKeys(dict):
+    '''Dictionary keyed with a multiple keys, either specified using standard dict lookup
+    using a tuple or as a keyword argument to getitem.'''
+    def __init__(self, keys):
+        self.keys = keys
+
+    def get(self, *args, **kw):
+        if args:
+            return super().getitem(args)
+        keytuple = tuple(kw[key] for key in self.keys)
+        return super().getitem(keytuple)
+
+class DictChild(XMLInfo):
+    def __init__(self, keys):
+        self.keys = keys
+    def initialvalue(self):
+        if len(self.keys) == 1:
+            return LDMLSingleKey(self.keys[0])
+        return LDMLMultipleKeys(self.keys)
+
+class TypedChild(DictChild):
+    '''Child node keyed with type= attribute.'''
+    def __init__(self):
+        super().__init__(('type',))
+
 class Attribute(XMLInfo):
     pass
 
         return klass
 
 class LDMLBase(metaclass=LDMLMeta):
+    _alias = False # object may have an alias attribute
     def __init__(self):
         for name, kind in self._fields.items():
             setattr(self, name, kind.initialvalue())
 class PresumedEmpty(LDMLBase):
     "Element is declared #PCDATA, but apparently never has content"
 
-# XXX: alias identities
+class PCDATA(LDMLBase):
+    "Element has only text content."
+
 class Identity(LDMLBase):
+    _alias = True
     version = MandatoryChild()
     generation = OptionalChild()
     language = MandatoryChild()
 class Generation(Empty):
     date = Attribute() # DateAttribute?
 
-class Language(PresumedEmpty):
+class Language(PCDATA):
     type = Attribute()
     draft = DraftAttribute()
     references = Attribute()
     alt = Attribute()
 
-class Territory(PresumedEmpty):
+class Territory(PCDATA):
     type = Attribute()
     draft = DraftAttribute()
     references = Attribute()
 # default
 # fallback
 
-# XXX alias
 class LocaleDisplayNames(LDMLBase):
+    _alias = True
     localeDisplayPattern = OptionalChild()
     languages = OptionalChild()
     scripts = OptionalChild()
 
     draft = DraftAttribute()
 
-class Languages(Incomplete):
-    pass
+class Languages(LDMLBase):
+    _alias = True
+    language = TypedChild()
+    special = MultipleChild()
+
+    draft = DraftAttribute()
+    
 
 class Scripts(Incomplete):
     pass
 
-class Territories(Incomplete):
-    pass
+class Territories(LDMLBase):
+    _alias = True
+    territory = TypedChild()
+    special = MultipleChild()
+
+    draft = DraftAttribute()
+    standard = Attribute() # deprecated
+    references = Attribute()
+    validSublocales = Attribute()
 
 class Variants(Incomplete):
     pass
         cnode = _buildtree(child, interning)
         if isinstance(field, MultipleChild):
             getattr(node, child.tag).append(cnode)
+        elif isinstance(field, DictChild):
+            if len(field.keys) == 1:
+                key = child.attrib[field.keys[0]]
+            else:
+                key = tuple(child.attrib[k] for k in field.keys)
+            getattr(node, child.tag)[key] = cnode
         else:
             setattr(node, child.tag, cnode)
     for name, field in node._fields.items():
         if isinstance(field, MandatoryChild):
             assert getattr(node, name) is not None, name
     if isinstance(node, (Empty, PresumedEmpty)):
-        assert not elem.text
+        assert not elem.text or not elem.text.strip(), (node, elem.text)
     else:
         node.value = elem.text
     return node