[docs]classRelationship(Serialisable):"""Represents many kinds of relationships."""tagname="Relationship"Type=String()Target=String()target=Alias("Target")TargetMode=String(allow_none=True)Id=String(allow_none=True)id=Alias("Id")def__init__(self,Id=None,Type=None,type=None,Target=None,TargetMode=None):""" `type` can be used as a shorthand with the default relationships namespace otherwise the `Type` must be a fully qualified URL """iftypeisnotNone:Type="{0}/{1}".format(REL_NS,type)self.Type=Typeself.Target=Targetself.TargetMode=TargetModeself.Id=Id

[docs]deffind(self,content_type):""" Find relationships by content-type NB. these content-types namespaced objects and different to the MIME-types in the package manifest :-( """forrinself.Relationship:ifr.Type==content_type:yieldr

[docs]defget_rels_path(path):""" Convert relative path to absolutes that can be loaded from a zip archive. The path to be passed in is that of containing object (workbook, worksheet, etc.) """folder,obj=posixpath.split(path)filename=posixpath.join(folder,'_rels','{0}.rels'.format(obj))returnfilename

[docs]defget_rel(archive,deps,id=None,cls=None):""" Get related object based on id or rel_type """ifnotany([id,cls]):raiseValueError("Either the id or the content type are required")ifidisnotNone:rel=deps[id]else:try:rel=next(deps.find(cls.rel_type))exceptStopIteration:# no known dependencyreturnpath=rel.targetsrc=archive.read(path)tree=fromstring(src)obj=cls.from_tree(tree)rels_path=get_rels_path(path)try:obj.deps=get_dependents(archive,rels_path)exceptKeyError:obj.deps=[]returnobj