Repository navigation
Provide method for getting namespace from any ID #176
Copy link
Copy link
Open
Description
Activity
Something like...
stix_package.id_.get_namespace() # returns {'namespace': 'http://example.com', 'alias': 'example'} # OR stix.utils.get_id_namespace(stix_package.id_) # returns {'namespace': 'http://example.com', 'alias': 'example'}
Here's my hack for id/idref namespaces... read-only, diff only includes Indicator.
diff --git a/stix/bindings/stix_common.py b/stix/bindings/stix_common.py index f550507..069ed79 100644 --- a/stix/bindings/stix_common.py +++ b/stix/bindings/stix_common.py @@ -342,6 +342,31 @@ def find_attr_value_(attr_name, node): value = attrs.get('{%s}%s' % (namespace, name, )) return value +def find_attr_value_qname(attr_name, node): + attrs = node.attrib + attr_parts = attr_name.split(':') + value = None + if len(attr_parts) == 1: + value = attrs.get(attr_name) + elif len(attr_parts) == 2: + prefix, name = attr_parts + namespace = node.nsmap.get(prefix) + if namespace is not None: + value = attrs.get('{%s}%s' % (namespace, name, )) + if value is None: + return None, None + val_parts = value.split(':') + if len(val_parts) == 1: + return value, None + elif len(val_parts) == 2: + prefix, data = val_parts + namespace = node.nsmap.get(prefix) + if namespace is not None: + return value, namespace + else: + raise ValueError("No namespace defined for qname prefix %s" % (prefix)) + else: + raise ValueError("Malformed qname %s" % (value)) class GDSParseError(Exception): pass @@ -2617,9 +2642,11 @@ class IndicatorBaseType(GeneratedsSuper): specified elsewhere.""" subclass = None superclass = None - def __init__(self, idref=None, id=None, timestamp=None): + def __init__(self, idref=None, id=None, timestamp=None, idrefns=None, idns=None): self.idref = _cast(None, idref) + self.idrefns = _cast(None, idrefns) self.id = _cast(None, id) + self.idns = _cast(None, idns) self.timestamp = _cast(None, timestamp) def factory(*args_, **kwargs_): if IndicatorBaseType.subclass: @@ -2627,9 +2654,9 @@ class IndicatorBaseType(GeneratedsSuper): else: return IndicatorBaseType(*args_, **kwargs_) factory = staticmethod(factory) - def get_idref(self): return self.idref + def get_idref(self): return self.idref, self.idrefns def set_idref(self, idref): self.idref = idref - def get_id(self): return self.id + def get_id(self): return self.id, self.idns def set_id(self, id): self.id = id def get_timestamp(self): return self.timestamp def set_timestamp(self, timestamp): self.timestamp = timestamp @@ -2674,14 +2701,16 @@ class IndicatorBaseType(GeneratedsSuper): nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] self.buildChildren(child, node, nodeName_) def buildAttributes(self, node, attrs, already_processed): - value = find_attr_value_('idref', node) + value, ns = find_attr_value_qname('idref', node) if value is not None and 'idref' not in already_processed: already_processed.add('idref') self.idref = value - value = find_attr_value_('id', node) + self.idrefns = ns + value, ns = find_attr_value_qname('id', node) if value is not None and 'id' not in already_processed: already_processed.add('id') self.id = value + self.idns = ns value = find_attr_value_('timestamp', node) if value is not None and 'timestamp' not in already_processed: already_processed.add('timestamp') diff --git a/stix/indicator/indicator.py b/stix/indicator/indicator.py index f3ab87f..517a50f 100644 --- a/stix/indicator/indicator.py +++ b/stix/indicator/indicator.py @@ -513,8 +513,8 @@ class Indicator(stix.Entity): if not return_obj: return_obj = cls() - return_obj.id_ = obj.get_id() - return_obj.idref = obj.get_idref() + return_obj.id_,return_obj.id_ns = obj.get_id() + return_obj.idref,return_obj.idref_ns = obj.get_idref() return_obj.timestamp = obj.get_timestamp() if isinstance(obj, cls._binding_class):
Metadata
Metadata
Assignees
Labels
No labels
STIX IDs are QNames, which contain namespaces as part of their form. We should provide either a utility method or a new class for IDs that has a method for returning the namespace along with the id itself.