示例#1
0
 def zAxis(self, row, zStructuralNode, zAspects, clearZchoices):
     if zStructuralNode is not None:
         gridBorder(self.gridColHdr, self.dataFirstCol, row, TOPBORDER, columnspan=2)
         gridBorder(self.gridColHdr, self.dataFirstCol, row, LEFTBORDER)
         gridBorder(self.gridColHdr, self.dataFirstCol, row, RIGHTBORDER, columnspan=2)
         label = zStructuralNode.header(lang=self.lang)
         hdr = gridHdr(self.gridColHdr, self.dataFirstCol, row,
                       label, 
                       anchor="w", columnspan=2,
                       wraplength=200, # in screen units
                       objectId=zStructuralNode.objectId(),
                       onClick=self.onClick)
 
         if zStructuralNode.choiceStructuralNodes: # combo box
             valueHeaders = [''.ljust(zChoiceStructuralNode.indent * 4) + # indent if nested choices 
                             (zChoiceStructuralNode.header(lang=self.lang) or '')
                             for zChoiceStructuralNode in zStructuralNode.choiceStructuralNodes]
             combobox = gridCombobox(
                          self.gridColHdr, self.dataFirstCol + 2, row,
                          values=valueHeaders,
                          selectindex=zStructuralNode.choiceNodeIndex,
                          columnspan=2,
                          comboboxselected=self.onComboBoxSelected)
             combobox.zStructuralNode = zStructuralNode
             combobox.zChoiceOrdIndex = row - 1
             combobox.objectId = hdr.objectId = zStructuralNode.objectId()
             gridBorder(self.gridColHdr, self.dataFirstCol + 3, row, RIGHTBORDER)
 
         if zStructuralNode.childStructuralNodes:
             for zStructuralNode in zStructuralNode.childStructuralNodes:
                 self.zAxis(row + 1, zStructuralNode, zAspects, clearZchoices)
         else: # nested-nost element, aspects process inheritance
             for aspect in aspectModels[self.aspectModel]:
                 for ruleAspect in aspectRuleAspects.get(aspect, (aspect,)):
                     if zStructuralNode.hasAspect(ruleAspect): #implies inheriting from other z axes
                         if ruleAspect == Aspect.DIMENSIONS:
                             for dim in (zStructuralNode.aspectValue(Aspect.DIMENSIONS) or emptyList):
                                 zAspects[dim].add(zStructuralNode)
                         else:
                             zAspects[ruleAspect].add(zStructuralNode)
示例#2
0
 def bodyCells(self, row, yParentStructuralNode, xStructuralNodes, zAspects, yChildrenFirst):
     if yParentStructuralNode is not None:
         rendrCntx = getattr(self.modelXbrl, "rendrCntx", None) # none for EU 2010 tables
         dimDefaults = self.modelXbrl.qnameDimensionDefaults
         for yStructuralNode in yParentStructuralNode.childStructuralNodes:
             if yChildrenFirst:
                 row = self.bodyCells(row, yStructuralNode, xStructuralNodes, zAspects, yChildrenFirst)
             if not yStructuralNode.isAbstract:
                 yAspects = defaultdict(set)
                 for aspect in aspectModels[self.aspectModel]:
                     for ruleAspect in aspectRuleAspects.get(aspect, (aspect,)):
                         if yStructuralNode.hasAspect(ruleAspect):
                             if ruleAspect == Aspect.DIMENSIONS:
                                 for dim in (yStructuralNode.aspectValue(Aspect.DIMENSIONS) or emptyList):
                                     yAspects[dim].add(yStructuralNode)
                             else:
                                 yAspects[ruleAspect].add(yStructuralNode)
                     
                 gridSpacer(self.gridBody, self.dataFirstCol, row, LEFTBORDER)
                 # data for columns of row
                 ignoreDimValidity = self.ignoreDimValidity.get()
                 for i, xStructuralNode in enumerate(xStructuralNodes):
                     xAspects = defaultdict(set)
                     for aspect in aspectModels[self.aspectModel]:
                         for ruleAspect in aspectRuleAspects.get(aspect, (aspect,)):
                             if xStructuralNode.hasAspect(ruleAspect):
                                 if ruleAspect == Aspect.DIMENSIONS:
                                     for dim in (xStructuralNode.aspectValue(Aspect.DIMENSIONS) or emptyList):
                                         xAspects[dim].add(xStructuralNode)
                                 else:
                                     xAspects[ruleAspect].add(xStructuralNode)
                     cellAspectValues = {}
                     matchableAspects = set()
                     for aspect in _DICT_SET(xAspects.keys()) | _DICT_SET(yAspects.keys()) | _DICT_SET(zAspects.keys()):
                         aspectValue = inheritedAspectValue(self, aspect, xAspects, yAspects, zAspects, xStructuralNode, yStructuralNode)
                         if dimDefaults.get(aspect) != aspectValue: # don't include defaulted dimensions
                             cellAspectValues[aspect] = aspectValue
                         matchableAspects.add(aspectModelAspect.get(aspect,aspect)) #filterable aspect from rule aspect
                     cellDefaultedDims = _DICT_SET(dimDefaults) - _DICT_SET(cellAspectValues.keys())
                     priItemQname = cellAspectValues.get(Aspect.CONCEPT)
                         
                     concept = self.modelXbrl.qnameConcepts.get(priItemQname)
                     conceptNotAbstract = concept is None or not concept.isAbstract
                     from arelle.ValidateXbrlDimensions import isFactDimensionallyValid
                     value = None
                     objectId = None
                     justify = None
                     fp = FactPrototype(self, cellAspectValues)
                     if conceptNotAbstract:
                         # reduce set of matchable facts to those with pri item qname and have dimension aspects
                         facts = self.modelXbrl.factsByQname[priItemQname] if priItemQname else self.modelXbrl.factsInInstance
                         for aspect in matchableAspects:  # trim down facts with explicit dimensions match or just present
                             if isinstance(aspect, QName):
                                 aspectValue = cellAspectValues.get(aspect, None)
                                 if isinstance(aspectValue, ModelDimensionValue):
                                     if aspectValue.isExplicit:
                                         dimMemQname = aspectValue.memberQname # match facts with this explicit value
                                     else:
                                         dimMemQname = None  # match facts that report this dimension
                                 elif isinstance(aspectValue, QName): 
                                     dimMemQname = aspectValue  # match facts that have this explicit value
                                 else:
                                     dimMemQname = None # match facts that report this dimension
                                 facts = facts & self.modelXbrl.factsByDimMemQname(aspect, dimMemQname)
                         for fact in facts:
                             if (all(aspectMatches(rendrCntx, fact, fp, aspect) 
                                     for aspect in matchableAspects) and
                                 all(fact.context.dimMemberQname(dim,includeDefaults=True) in (dimDefaults[dim], None)
                                     for dim in cellDefaultedDims)):
                                 if yStructuralNode.hasValueExpression(xStructuralNode):
                                     value = yStructuralNode.evalValueExpression(fact, xStructuralNode)
                                 else:
                                     value = fact.effectiveValue
                                 objectId = fact.objectId()
                                 justify = "right" if fact.isNumeric else "left"
                                 break
                     if (conceptNotAbstract and
                         (value is not None or ignoreDimValidity or isFactDimensionallyValid(self, fp))):
                         if objectId is None:
                             objectId = "f{0}".format(len(self.factPrototypes))
                             self.factPrototypes.append(fp)  # for property views
                         gridCell(self.gridBody, self.dataFirstCol + i, row, value, justify=justify, 
                                  width=12, # width is in characters, not screen units
                                  objectId=objectId, onClick=self.onClick)
                     else:
                         fp.clear()  # dereference
                         gridSpacer(self.gridBody, self.dataFirstCol + i, row, CENTERCELL)
                     gridSpacer(self.gridBody, self.dataFirstCol + i, row, RIGHTBORDER)
                     gridSpacer(self.gridBody, self.dataFirstCol + i, row, BOTTOMBORDER)
                 row += 1
             if not yChildrenFirst:
                 row = self.bodyCells(row, yStructuralNode, xStructuralNodes, zAspects, yChildrenFirst)
         return row
示例#3
0
    def bodyCells(self, row, yParentStructuralNode, xStructuralNodes, zAspects,
                  yChildrenFirst):
        if yParentStructuralNode is not None:
            rendrCntx = getattr(self.modelXbrl, "rendrCntx",
                                None)  # none for EU 2010 tables
            dimDefaults = self.modelXbrl.qnameDimensionDefaults
            for yStructuralNode in yParentStructuralNode.childStructuralNodes:
                if yChildrenFirst:
                    row = self.bodyCells(row, yStructuralNode,
                                         xStructuralNodes, zAspects,
                                         yChildrenFirst)
                if not yStructuralNode.isAbstract:
                    yAspects = defaultdict(set)
                    for aspect in aspectModels[self.aspectModel]:
                        for ruleAspect in aspectRuleAspects.get(
                                aspect, (aspect, )):
                            if yStructuralNode.hasAspect(ruleAspect):
                                if ruleAspect == Aspect.DIMENSIONS:
                                    for dim in (yStructuralNode.aspectValue(
                                            Aspect.DIMENSIONS) or emptyList):
                                        yAspects[dim].add(yStructuralNode)
                                else:
                                    yAspects[ruleAspect].add(yStructuralNode)

                    gridSpacer(self.gridBody, self.dataFirstCol, row,
                               LEFTBORDER)
                    # data for columns of row
                    ignoreDimValidity = self.ignoreDimValidity.get()
                    for i, xStructuralNode in enumerate(xStructuralNodes):
                        xAspects = defaultdict(set)
                        for aspect in aspectModels[self.aspectModel]:
                            for ruleAspect in aspectRuleAspects.get(
                                    aspect, (aspect, )):
                                if xStructuralNode.hasAspect(ruleAspect):
                                    if ruleAspect == Aspect.DIMENSIONS:
                                        for dim in (
                                                xStructuralNode.aspectValue(
                                                    Aspect.DIMENSIONS)
                                                or emptyList):
                                            xAspects[dim].add(xStructuralNode)
                                    else:
                                        xAspects[ruleAspect].add(
                                            xStructuralNode)
                        cellAspectValues = {}
                        matchableAspects = set()
                        for aspect in _DICT_SET(xAspects.keys()) | _DICT_SET(
                                yAspects.keys()) | _DICT_SET(zAspects.keys()):
                            aspectValue = inheritedAspectValue(
                                self, aspect, xAspects, yAspects, zAspects,
                                xStructuralNode, yStructuralNode)
                            if dimDefaults.get(
                                    aspect
                            ) != aspectValue:  # don't include defaulted dimensions
                                cellAspectValues[aspect] = aspectValue
                            matchableAspects.add(
                                aspectModelAspect.get(aspect, aspect)
                            )  #filterable aspect from rule aspect
                        cellDefaultedDims = _DICT_SET(dimDefaults) - _DICT_SET(
                            cellAspectValues.keys())
                        priItemQname = cellAspectValues.get(Aspect.CONCEPT)

                        concept = self.modelXbrl.qnameConcepts.get(
                            priItemQname)
                        conceptNotAbstract = concept is None or not concept.isAbstract
                        from arelle.ValidateXbrlDimensions import isFactDimensionallyValid
                        value = None
                        objectId = None
                        justify = None
                        fp = FactPrototype(self, cellAspectValues)
                        if conceptNotAbstract:
                            # reduce set of matchable facts to those with pri item qname and have dimension aspects
                            facts = self.modelXbrl.factsByQname[
                                priItemQname] if priItemQname else self.modelXbrl.factsInInstance
                            for aspect in matchableAspects:  # trim down facts with explicit dimensions match or just present
                                if isinstance(aspect, QName):
                                    aspectValue = cellAspectValues.get(
                                        aspect, None)
                                    if isinstance(aspectValue,
                                                  ModelDimensionValue):
                                        if aspectValue.isExplicit:
                                            dimMemQname = aspectValue.memberQname  # match facts with this explicit value
                                        else:
                                            dimMemQname = None  # match facts that report this dimension
                                    elif isinstance(aspectValue, QName):
                                        dimMemQname = aspectValue  # match facts that have this explicit value
                                    else:
                                        dimMemQname = None  # match facts that report this dimension
                                    facts = facts & self.modelXbrl.factsByDimMemQname(
                                        aspect, dimMemQname)
                            for fact in facts:
                                if (all(
                                        aspectMatches(rendrCntx, fact, fp,
                                                      aspect)
                                        for aspect in matchableAspects)
                                        and all(
                                            fact.context.dimMemberQname(
                                                dim, includeDefaults=True) in (
                                                    dimDefaults[dim], None)
                                            for dim in cellDefaultedDims)):
                                    if yStructuralNode.hasValueExpression(
                                            xStructuralNode):
                                        value = yStructuralNode.evalValueExpression(
                                            fact, xStructuralNode)
                                    else:
                                        value = fact.effectiveValue
                                    objectId = fact.objectId()
                                    justify = "right" if fact.isNumeric else "left"
                                    break
                        if (conceptNotAbstract
                                and (value is not None or ignoreDimValidity
                                     or isFactDimensionallyValid(self, fp))):
                            if objectId is None:
                                objectId = "f{0}".format(
                                    len(self.factPrototypes))
                                self.factPrototypes.append(
                                    fp)  # for property views
                            gridCell(
                                self.gridBody,
                                self.dataFirstCol + i,
                                row,
                                value,
                                justify=justify,
                                width=
                                12,  # width is in characters, not screen units
                                objectId=objectId,
                                onClick=self.onClick)
                        else:
                            fp.clear()  # dereference
                            gridSpacer(self.gridBody, self.dataFirstCol + i,
                                       row, CENTERCELL)
                        gridSpacer(self.gridBody, self.dataFirstCol + i, row,
                                   RIGHTBORDER)
                        gridSpacer(self.gridBody, self.dataFirstCol + i, row,
                                   BOTTOMBORDER)
                    row += 1
                if not yChildrenFirst:
                    row = self.bodyCells(row, yStructuralNode,
                                         xStructuralNodes, zAspects,
                                         yChildrenFirst)
            return row
示例#4
0
    def zAxis(self, row, zStructuralNode, zAspects, clearZchoices):
        if zStructuralNode is not None:
            gridBorder(self.gridColHdr,
                       self.dataFirstCol,
                       row,
                       TOPBORDER,
                       columnspan=2)
            gridBorder(self.gridColHdr, self.dataFirstCol, row, LEFTBORDER)
            gridBorder(self.gridColHdr,
                       self.dataFirstCol,
                       row,
                       RIGHTBORDER,
                       columnspan=2)
            label = zStructuralNode.header(lang=self.lang)
            hdr = gridHdr(
                self.gridColHdr,
                self.dataFirstCol,
                row,
                label,
                anchor="w",
                columnspan=2,
                wraplength=200,  # in screen units
                objectId=zStructuralNode.objectId(),
                onClick=self.onClick)

            if zStructuralNode.choiceStructuralNodes:  # combo box
                valueHeaders = [
                    ''.ljust(zChoiceStructuralNode.indent * 4)
                    +  # indent if nested choices 
                    (zChoiceStructuralNode.header(lang=self.lang) or '')
                    for zChoiceStructuralNode in
                    zStructuralNode.choiceStructuralNodes
                ]
                combobox = gridCombobox(
                    self.gridColHdr,
                    self.dataFirstCol + 2,
                    row,
                    values=valueHeaders,
                    selectindex=zStructuralNode.choiceNodeIndex,
                    columnspan=2,
                    comboboxselected=self.onComboBoxSelected)
                combobox.zStructuralNode = zStructuralNode
                combobox.zChoiceOrdIndex = row - 1
                combobox.objectId = hdr.objectId = zStructuralNode.objectId()
                gridBorder(self.gridColHdr, self.dataFirstCol + 3, row,
                           RIGHTBORDER)

            if zStructuralNode.childStructuralNodes:
                for zStructuralNode in zStructuralNode.childStructuralNodes:
                    self.zAxis(row + 1, zStructuralNode, zAspects,
                               clearZchoices)
            else:  # nested-nost element, aspects process inheritance
                for aspect in aspectModels[self.aspectModel]:
                    for ruleAspect in aspectRuleAspects.get(
                            aspect, (aspect, )):
                        if zStructuralNode.hasAspect(
                                ruleAspect
                        ):  #implies inheriting from other z axes
                            if ruleAspect == Aspect.DIMENSIONS:
                                for dim in (zStructuralNode.aspectValue(
                                        Aspect.DIMENSIONS) or emptyList):
                                    zAspects[dim].add(zStructuralNode)
                            else:
                                zAspects[ruleAspect].add(zStructuralNode)
示例#5
0
 def bodyCells(self, row, yParentStructuralNode, xStructuralNodes, zAspects, yChildrenFirst):
     if yParentStructuralNode is not None:
         rendrCntx = getattr(self.modelXbrl, "rendrCntx", None) # none for EU 2010 tables
         dimDefaults = self.modelXbrl.qnameDimensionDefaults
         for yStructuralNode in yParentStructuralNode.childStructuralNodes:
             if yChildrenFirst:
                 row = self.bodyCells(row, yStructuralNode, xStructuralNodes, zAspects, yChildrenFirst)
             if not yStructuralNode.isAbstract:
                 if self.type == XML:
                     self.xCells = etree.SubElement(self.yCells, tableModelQName("cells"),
                                                    attrib={"disposition": "x"})
                 yAspects = defaultdict(set)
                 for aspect in aspectModels[self.aspectModel]:
                     for ruleAspect in aspectRuleAspects.get(aspect, (aspect,)):
                         if yStructuralNode.hasAspect(ruleAspect):
                             if ruleAspect == Aspect.DIMENSIONS:
                                 for dim in (yStructuralNode.aspectValue(Aspect.DIMENSIONS) or emptyList):
                                     yAspects[dim].add(yStructuralNode)
                             else:
                                 yAspects[ruleAspect].add(yStructuralNode)
                 # data for columns of rows
                 ignoreDimValidity = self.ignoreDimValidity.get()
                 for i, xStructuralNode in enumerate(xStructuralNodes):
                     xAspects = defaultdict(set)
                     for aspect in aspectModels[self.aspectModel]:
                         for ruleAspect in aspectRuleAspects.get(aspect, (aspect,)):
                             if xStructuralNode.hasAspect(ruleAspect):
                                 if ruleAspect == Aspect.DIMENSIONS:
                                     for dim in (xStructuralNode.aspectValue(Aspect.DIMENSIONS) or emptyList):
                                         xAspects[dim].add(xStructuralNode)
                                 else:
                                     xAspects[ruleAspect].add(xStructuralNode)
                     cellAspectValues = {}
                     matchableAspects = set()
                     for aspect in _DICT_SET(xAspects.keys()) | _DICT_SET(yAspects.keys()) | _DICT_SET(zAspects.keys()):
                         aspectValue = inheritedAspectValue(self, aspect, xAspects, yAspects, zAspects, xStructuralNode, yStructuralNode)
                         if dimDefaults.get(aspect) != aspectValue: # don't include defaulted dimensions
                             cellAspectValues[aspect] = aspectValue
                         matchableAspects.add(aspectModelAspect.get(aspect,aspect)) #filterable aspect from rule aspect
                     cellDefaultedDims = _DICT_SET(dimDefaults) - _DICT_SET(cellAspectValues.keys())
                     priItemQname = cellAspectValues.get(Aspect.CONCEPT)
                         
                     concept = self.modelXbrl.qnameConcepts.get(priItemQname)
                     conceptNotAbstract = concept is None or not concept.isAbstract
                     from arelle.ValidateXbrlDimensions import isFactDimensionallyValid
                     value = None
                     objectId = None
                     justify = None
                     fp = FactPrototype(self, cellAspectValues)
                     if conceptNotAbstract:
                         # reduce set of matchable facts to those with pri item qname and have dimension aspects
                         facts = self.modelXbrl.factsByQname[priItemQname] if priItemQname else self.modelXbrl.factsInInstance
                         for aspect in matchableAspects:  # trim down facts with explicit dimensions match or just present
                             if isinstance(aspect, QName):
                                 aspectValue = cellAspectValues.get(aspect, None)
                                 if isinstance(aspectValue, ModelDimensionValue):
                                     if aspectValue.isExplicit:
                                         dimMemQname = aspectValue.memberQname # match facts with this explicit value
                                     else:
                                         dimMemQname = None  # match facts that report this dimension
                                 elif isinstance(aspectValue, QName): 
                                     dimMemQname = aspectValue  # match facts that have this explicit value
                                 else:
                                     dimMemQname = None # match facts that report this dimension
                                 facts = facts & self.modelXbrl.factsByDimMemQname(aspect, dimMemQname)
                         for fact in facts:
                             if (all(aspectMatches(rendrCntx, fact, fp, aspect) 
                                     for aspect in matchableAspects) and
                                 all(fact.context.dimMemberQname(dim,includeDefaults=True) in (dimDefaults[dim], None)
                                     for dim in cellDefaultedDims)):
                                 if yStructuralNode.hasValueExpression(xStructuralNode):
                                     value = yStructuralNode.evalValueExpression(fact, xStructuralNode)
                                 else:
                                     value = fact.effectiveValue
                                 justify = "right" if fact.isNumeric else "left"
                                 break
                     if conceptNotAbstract:
                         if value is not None or ignoreDimValidity or isFactDimensionallyValid(self, fp):
                             if self.type == HTML:
                                 etree.SubElement(self.rowElts[row - 1], 
                                                  "{http://www.w3.org/1999/xhtml}td",
                                                  attrib={"class":"cell",
                                                          "style":"text-align:{0};width:8em".format(justify)}
                                                  ).text = value or "\u00A0"
                             elif self.type == XML:
                                 if value is not None and fact is not None:
                                     self.xCells.append(etree.Comment("{0}: context {1}, value {2}, file {3}, line {4}"
                                                                      .format(fact.qname,
                                                                              fact.contextID,
                                                                              value,
                                                                              fact.modelDocument.basename, 
                                                                              fact.sourceline)))
 
                                 cellElt = etree.SubElement(self.xCells, tableModelQName("cell"))
                                 etree.SubElement(cellElt, tableModelQName("fact")
                                                  ).text = '#' + elementFragmentIdentifier(fact)
                         else:
                             if self.type == HTML:
                                 etree.SubElement(self.rowElts[row - 1], 
                                                  "{http://www.w3.org/1999/xhtml}td",
                                                  attrib={"class":"blockedCell",
                                                          "style":"text-align:{0};width:8em".format(justify)}
                                                  ).text = "\u00A0\u00A0"
                             elif self.type == XML:
                                 etree.SubElement(self.xCells, tableModelQName("cell"),
                                                  attrib={"blocked":"true"})
                     else: # concept is abstract
                         if self.type == HTML:
                             etree.SubElement(self.rowElts[row - 1], 
                                              "{http://www.w3.org/1999/xhtml}td",
                                              attrib={"class":"abstractCell",
                                                      "style":"text-align:{0};width:8em".format(justify)}
                                              ).text = "\u00A0\u00A0"
                         elif self.type == XML:
                             etree.SubElement(self.xCells, tableModelQName("cell"),
                                              attrib={"abstract":"true"})
                     fp.clear()  # dereference
                 row += 1
             if not yChildrenFirst:
                 row = self.bodyCells(row, yStructuralNode, xStructuralNodes, zAspects, yChildrenFirst)
     return row
         
示例#6
0
    def zAxis(self, row, zStructuralNode, zAspects, discriminatorsTable):
        if zStructuralNode is not None:
            label = zStructuralNode.header(lang=self.lang)
            choiceLabel = None
            if zStructuralNode.choiceStructuralNodes: # same as combo box selection in GUI mode
                if not discriminatorsTable:
                    self.zStrNodesWithChoices.insert(0, zStructuralNode) # iteration from last is first
                try:
                    zChoiceStructuralNode = zStructuralNode.choiceStructuralNodes[zStructuralNode.choiceNodeIndex]
                    choiceLabel = zChoiceStructuralNode.header(lang=self.lang)
                    if not label and choiceLabel:
                        label = choiceLabel # no header for choice
                        choiceLabel = None
                except KeyError:
                    pass
            if choiceLabel:
                if self.dataCols > 3:
                    zLabelSpan = 2
                else:
                    zLabelSpan = 1
                zChoiceLabelSpan = self.dataCols - zLabelSpan
            else:
                zLabelSpan = self.dataCols
            if self.type == HTML:
                etree.SubElement(self.rowElts[row-1], "{http://www.w3.org/1999/xhtml}th",
                                 attrib={"class":"zAxisHdr",
                                         "style":"max-width:200pt;text-align:left;border-bottom:.5pt solid windowtext",
                                         "colspan": str(zLabelSpan)} # "2"}
                                 ).text = label
                if choiceLabel:
                    etree.SubElement(self.rowElts[row-1], "{http://www.w3.org/1999/xhtml}th",
                                     attrib={"class":"zAxisHdr",
                                             "style":"max-width:200pt;text-align:left;border-bottom:.5pt solid windowtext",
                                             "colspan": str(zChoiceLabelSpan)} # "2"}
                                     ).text = choiceLabel
            elif self.type == XML:
                # per JS, no header elements inside each table
                if discriminatorsTable:
                    hdrElt = etree.SubElement(self.zHdrsElt, tableModelQName("header"))
                    self.structuralNodeModelElements.append((zStructuralNode, hdrElt))
                    if zStructuralNode.choiceStructuralNodes: # same as combo box selection in GUI mode
                        # hdrElt.set("label", label)
                        if discriminatorsTable:
                            for choiceStructuralNode in zStructuralNode.choiceStructuralNodes:
                                choiceLabel = choiceStructuralNode.header(lang=self.lang)
                                elt = etree.SubElement(hdrElt, tableModelQName("label"))
                                if choiceLabel:
                                    elt.text = choiceLabel
                        #else: # choiceLabel from above 
                        #    etree.SubElement(hdrElt, tableModelQName("label")
                        #                     ).text = choiceLabel
                    else: # no combo choices, single label
                        elt = etree.SubElement(hdrElt, tableModelQName("label"))
                        if label:
                            elt.text = label
                else:
                    if choiceLabel: # same as combo box selection in GUI mode
                        comment = etree.Comment("Z axis {0}: {1}".format(label, choiceLabel))
                    else:
                        comment = etree.Comment("Z axis: {0}".format(label))
                    if isinstance(self.zHdrsElt, etree._Comment):
                        self.zHdrsElt.addnext(comment)
                    else:
                        self.zHdrsElt.addprevious(comment)
                    self.zHdrsElt = comment                    

            if zStructuralNode.childStructuralNodes:
                for zStructuralNode in zStructuralNode.childStructuralNodes:
                    self.zAxis(row + 1, zStructuralNode, zAspects, discriminatorsTable)
            else: # nested-nost element, aspects process inheritance
                for aspect in aspectModels[self.aspectModel]:
                    for ruleAspect in aspectRuleAspects.get(aspect, (aspect,)):
                        if zStructuralNode.hasAspect(ruleAspect): #implies inheriting from other z axes
                            if ruleAspect == Aspect.DIMENSIONS:
                                for dim in (zStructuralNode.aspectValue(Aspect.DIMENSIONS) or emptyList):
                                    zAspects[dim].add(zStructuralNode)
                            else:
                                zAspects[ruleAspect].add(zStructuralNode)