Пример #1
0
def inheritedAspectValue(view, aspect, xAspects, yAspects, zAspects, xOrdCntx, yOrdCntx):
    ords = xAspects.get(aspect, emptySet) | yAspects.get(aspect, emptySet) | zAspects.get(aspect, emptySet)
    structuralNode = None
    if len(ords) == 1:
        structuralNode = ords.pop()
    elif len(ords) > 1:
        if aspect == Aspect.LOCATION:
            hasClash = False
            for _ordCntx in ords:
                if not _ordCntx.definitionNode.aspectValueDependsOnVars(aspect):
                    if structuralNode:
                        hasClash = True
                    else:
                        structuralNode = _ordCntx 
        else:
            hasClash = True
            
        if hasClash:
            from arelle.ModelFormulaObject import aspectStr
            view.modelXbrl.error("xbrlte:axisAspectClash",
                _("Aspect %(aspect)s covered by multiple axes."),
                modelObject=view.modelTable, aspect=aspectStr(aspect))
    if structuralNode:
        definitionNode = structuralNode.definitionNode
        if definitionNode.aspectValueDependsOnVars(aspect):
            return xOrdCntx.evaluate(definitionNode, 
                                     definitionNode.aspectValue, 
                                     otherOrdinate=yOrdCntx,
                                     evalArgs=(aspect,))
        return structuralNode.aspectValue(aspect)
    return None 
Пример #2
0
def inheritedAspectValue(view, aspect, xAspects, yAspects, zAspects, xOrdCntx, yOrdCntx):
    ords = xAspects.get(aspect, emptySet) | yAspects.get(aspect, emptySet) | zAspects.get(aspect, emptySet)
    structuralNode = None
    if len(ords) == 1:
        structuralNode = ords.pop()
    elif len(ords) > 1:
        if aspect == Aspect.LOCATION:
            hasClash = False
            for _ordCntx in ords:
                if not _ordCntx.definitionNode.aspectValueDependsOnVars(aspect):
                    if structuralNode:
                        hasClash = True
                    else:
                        structuralNode = _ordCntx 
        else:
            hasClash = True
            
        if hasClash:
            from arelle.ModelFormulaObject import aspectStr
            view.modelXbrl.error("xbrlte:axisAspectClash",
                _("Aspect %(aspect)s covered by multiple axes."),
                modelObject=view.modelTable, aspect=aspectStr(aspect))
    if structuralNode:
        definitionNode = structuralNode.definitionNode
        if definitionNode.aspectValueDependsOnVars(aspect):
            return xOrdCntx.evaluate(definitionNode, 
                                     definitionNode.aspectValue, 
                                     otherOrdinate=yOrdCntx,
                                     evalArgs=(aspect,))
        return structuralNode.aspectValue(aspect)
    return None 
def checkBreakdownLeafNodeAspects(modelXbrl, modelTable, tblAxisRel, aspectsCovered, breakdownAspects):
    definitionNode = tblAxisRel.toModelObject
    if isinstance(definitionNode, (ModelDefinitionNode, ModelEuAxisCoord)):
        for aspect in definitionNode.aspectsCovered():
            aspectsCovered.add(aspect)
    definitionNodeHasChild = False
    for axisSubtreeRel in modelXbrl.relationshipSet((XbrlConst.tableBreakdownTree, XbrlConst.tableBreakdownTreeMMDD, XbrlConst.tableBreakdownTree201305, XbrlConst.tableDefinitionNodeSubtree, XbrlConst.tableDefinitionNodeSubtreeMMDD, XbrlConst.tableDefinitionNodeSubtree201305, XbrlConst.tableDefinitionNodeSubtree201301, XbrlConst.tableAxisSubtree2011)).fromModelObject(definitionNode):
        checkBreakdownLeafNodeAspects(modelXbrl, modelTable, axisSubtreeRel, aspectsCovered, breakdownAspects)
        definitionNodeHasChild = True
    
    if not definitionNode.isAbstract: # this is a leaf node
        missingAspects = set(aspect
                             for aspect in breakdownAspects
                             if aspect not in aspectsCovered and
                                aspect != Aspect.DIMENSIONS and not isinstance(aspect,QName))
        if (missingAspects):
            modelXbrl.error("xbrlte:missingAspectValue",
                _("%(definitionNode)s %(xlinkLabel)s does not define an aspect for %(aspect)s"),
                modelObject=(modelTable,definitionNode), xlinkLabel=definitionNode.xlinkLabel, definitionNode=definitionNode.localName,
                aspect=', '.join(aspectStr(aspect) for aspect in missingAspects))
Пример #4
0
def checkBreakdownLeafNodeAspects(modelXbrl, modelTable, tblAxisRel, parentAspectsCovered, breakdownAspects):
    definitionNode = tblAxisRel.toModelObject
    aspectsCovered = parentAspectsCovered.copy()
    if isinstance(definitionNode, (ModelDefinitionNode, ModelEuAxisCoord)):
        for aspect in definitionNode.aspectsCovered():
            aspectsCovered.add(aspect)
        definitionNodeHasChild = False
        for axisSubtreeRel in modelXbrl.relationshipSet((XbrlConst.tableBreakdownTree, XbrlConst.tableBreakdownTreeMMDD, XbrlConst.tableBreakdownTree201305, XbrlConst.tableDefinitionNodeSubtree, XbrlConst.tableDefinitionNodeSubtreeMMDD, XbrlConst.tableDefinitionNodeSubtree201305, XbrlConst.tableDefinitionNodeSubtree201301, XbrlConst.tableAxisSubtree2011)).fromModelObject(definitionNode):
            checkBreakdownLeafNodeAspects(modelXbrl, modelTable, axisSubtreeRel, aspectsCovered, breakdownAspects)
            definitionNodeHasChild = True
        
        if not definitionNode.isAbstract and not isinstance(definitionNode, ModelBreakdown): # this is a leaf node
            missingAspects = set(aspect
                                 for aspect in breakdownAspects
                                 if aspect not in aspectsCovered and
                                    aspect != Aspect.DIMENSIONS and not isinstance(aspect,QName))
            if (missingAspects):
                modelXbrl.error("xbrlte:missingAspectValue",
                    _("%(definitionNode)s %(xlinkLabel)s does not define an aspect for %(aspect)s"),
                    modelObject=(modelTable,definitionNode), xlinkLabel=definitionNode.xlinkLabel, definitionNode=definitionNode.localName,
                    aspect=', '.join(aspectStr(aspect) for aspect in missingAspects))
Пример #5
0
def checkBreakdownDefinitionNode(modelXbrl, modelTable, tblAxisRel,
                                 tblAxisDisposition, uncoverableAspects,
                                 aspectsCovered):
    definitionNode = tblAxisRel.toModelObject
    hasCoveredAspect = False
    if isinstance(definitionNode, (ModelDefinitionNode, ModelEuAxisCoord)):
        for aspect in definitionNode.aspectsCovered():
            aspectsCovered.add(aspect)
            if (aspect in uncoverableAspects
                    or (isinstance(aspect, QName)
                        and modelTable.aspectModel == 'non-dimensional')):
                modelXbrl.error(
                    "xbrlte:axisAspectModelMismatch",
                    _("%(definitionNode)s %(xlinkLabel)s, aspect model %(aspectModel)s, aspect %(aspect)s not allowed"
                      ),
                    modelObject=modelTable,
                    definitionNode=definitionNode.localName,
                    xlinkLabel=definitionNode.xlinkLabel,
                    aspectModel=modelTable.aspectModel,
                    aspect=str(aspect)
                    if isinstance(aspect, QName) else Aspect.label[aspect])
            hasCoveredAspect = True
            if aspect in modelTable.priorAspectAxisDisposition:
                otherAxisDisposition, otherDefinitionNode = modelTable.priorAspectAxisDisposition[
                    aspect]
                if tblAxisDisposition != otherAxisDisposition and aspect != Aspect.DIMENSIONS:
                    modelXbrl.error(
                        "xbrlte:aspectClashBetweenBreakdowns",
                        _("%(definitionNode)s %(xlinkLabel)s, aspect %(aspect)s defined on axes of disposition %(axisDisposition)s and %(axisDisposition2)s"
                          ),
                        modelObject=(modelTable, definitionNode,
                                     otherDefinitionNode),
                        definitionNode=definitionNode.localName,
                        xlinkLabel=definitionNode.xlinkLabel,
                        axisDisposition=tblAxisDisposition,
                        axisDisposition2=otherAxisDisposition,
                        aspect=str(aspect)
                        if isinstance(aspect, QName) else Aspect.label[aspect])
            else:
                modelTable.priorAspectAxisDisposition[aspect] = (
                    tblAxisDisposition, definitionNode)
        ruleSetChildren = XmlUtil.children(definitionNode,
                                           definitionNode.namespaceURI,
                                           "ruleSet")
        if definitionNode.isMerged:
            if ruleSetChildren:
                modelXbrl.error(
                    "xbrlte:mergedRuleNodeWithTaggedRuleSet",
                    _("Merged %(definitionNode)s %(xlinkLabel)s has tagged rule set(s)"
                      ),
                    modelObject=[modelTable, definitionNode] + ruleSetChildren,
                    definitionNode=definitionNode.localName,
                    xlinkLabel=definitionNode.xlinkLabel)
            labelRels = modelXbrl.relationshipSet(
                XbrlConst.elementLabel).fromModelObject(definitionNode)
            if labelRels:
                modelXbrl.error(
                    "xbrlte:invalidUseOfLabel",
                    _("Merged %(definitionNode)s %(xlinkLabel)s has label(s)"),
                    modelObject=[modelTable, definitionNode] +
                    [r.toModelObject for r in labelRels],
                    definitionNode=definitionNode.localName,
                    xlinkLabel=definitionNode.xlinkLabel)
            if not definitionNode.isAbstract:
                modelXbrl.error(
                    "xbrlte:nonAbstractMergedRuleNode",
                    _("Merged %(definitionNode)s %(xlinkLabel)s is not abstract"
                      ),
                    modelObject=(modelTable, definitionNode),
                    definitionNode=definitionNode.localName,
                    xlinkLabel=definitionNode.xlinkLabel)
    if isinstance(definitionNode, ModelRuleDefinitionNode):
        tagConstraintSets = {}
        otherConstraintSet = None
        # must look at xml constructs for duplicates
        for ruleSet in XmlUtil.children(definitionNode,
                                        definitionNode.namespaceURI,
                                        "ruleSet"):
            tag = ruleSet.tagName
            if tag is not None:  # named constraint sets only
                for aspect in ruleSet.aspectsCovered():
                    if aspect != Aspect.DIMENSIONS:
                        modelTable.aspectsInTaggedConstraintSets.add(aspect)
            if tag in tagConstraintSets:
                modelXbrl.error(
                    "xbrlte:duplicateTag",
                    _("%(definitionNode)s %(xlinkLabel)s duplicate rule set tags %(tag)s"
                      ),
                    modelObject=(modelTable, definitionNode,
                                 tagConstraintSets[tag], ruleSet),
                    definitionNode=definitionNode.localName,
                    xlinkLabel=definitionNode.xlinkLabel,
                    tag=tag)
            else:
                tagConstraintSets[tag] = ruleSet
        for tag, constraintSet in definitionNode.constraintSets.items():
            if otherConstraintSet is None:
                otherConstraintSet = constraintSet
            elif otherConstraintSet.aspectsCovered(
            ) != constraintSet.aspectsCovered():
                modelXbrl.error(
                    "xbrlte:constraintSetAspectMismatch",
                    _("%(definitionNode)s %(xlinkLabel)s constraint set mismatches between %(tag1)s and %(tag2)s in constraints %(aspects)s"
                      ),
                    modelObject=(modelTable, definitionNode,
                                 otherConstraintSet, constraintSet),
                    definitionNode=definitionNode.localName,
                    xlinkLabel=definitionNode.xlinkLabel,
                    tag1=otherConstraintSet.tagName,
                    tag2=constraintSet.tagName,
                    aspects=", ".join(
                        aspectStr(aspect)
                        for aspect in otherConstraintSet.aspectsCovered()
                        ^ constraintSet.aspectsCovered()
                        if aspect != Aspect.DIMENSIONS))
    if isinstance(definitionNode, ModelDimensionRelationshipDefinitionNode):
        hasCoveredAspect = True
        if modelTable.aspectModel == 'non-dimensional':
            modelXbrl.error(
                "xbrlte:axisAspectModelMismatch",
                _("DimensionRelationship axis %(xlinkLabel)s can't be used in non-dimensional aspect model"
                  ),
                modelObject=(modelTable, definitionNode),
                xlinkLabel=definitionNode.xlinkLabel)
    definitionNodeHasChild = False
    for axisSubtreeRel in modelXbrl.relationshipSet(
        (XbrlConst.tableBreakdownTree, XbrlConst.tableBreakdownTreeMMDD,
         XbrlConst.tableBreakdownTree201305,
         XbrlConst.tableDefinitionNodeSubtree,
         XbrlConst.tableDefinitionNodeSubtreeMMDD,
         XbrlConst.tableDefinitionNodeSubtree201305,
         XbrlConst.tableDefinitionNodeSubtree201301,
         XbrlConst.tableAxisSubtree2011)).fromModelObject(definitionNode):
        if checkBreakdownDefinitionNode(modelXbrl, modelTable, axisSubtreeRel,
                                        tblAxisDisposition, uncoverableAspects,
                                        aspectsCovered):
            hasCoveredAspect = True  # something below was covering
        definitionNodeHasChild = True
    if isinstance(definitionNode, ModelFilterDefinitionNode):
        for aspect in definitionNode.aspectsCovered():
            if isinstance(aspect, QName):  # dimension aspect
                concept = modelXbrl.qnameConcepts.get(aspect)
                if concept is None or not concept.isDimensionItem:
                    modelXbrl.error(
                        "xbrlte:invalidDimensionQNameOnAspectNode",
                        _("Aspect node %(xlinkLabel)s dimensional aspect %(dimension)s is not a dimension"
                          ),
                        modelObject=(modelTable, definitionNode),
                        xlinkLabel=definitionNode.xlinkLabel,
                        dimension=aspect)

    if not definitionNodeHasChild:
        if (definitionNode.namespaceURI
                in ("http://www.eurofiling.info/2010/rendering",
                    "http://xbrl.org/2011/table") and not hasCoveredAspect):
            modelXbrl.error(
                "xbrlte:aspectValueNotDefinedByOrdinate",
                _("%(definitionNode)s %(xlinkLabel)s does not define an aspect"
                  ),
                modelObject=(modelTable, definitionNode),
                xlinkLabel=definitionNode.xlinkLabel,
                definitionNode=definitionNode.localName)
        if (isinstance(definitionNode, ModelClosedDefinitionNode)
                and definitionNode.isAbstract):
            modelXbrl.error(
                "xbrlte:abstractRuleNodeNoChildren",
                _("Abstract %(definitionNode)s %(xlinkLabel)s has no children"
                  ),
                modelObject=(modelTable, definitionNode),
                xlinkLabel=definitionNode.xlinkLabel,
                definitionNode=definitionNode.localName)
    return hasCoveredAspect
Пример #6
0
def checkBreakdownDefinitionNode(modelXbrl, modelTable, tblAxisRel, tblAxisDisposition, uncoverableAspects, aspectsCovered):
    definitionNode = tblAxisRel.toModelObject
    hasCoveredAspect = False
    if isinstance(definitionNode, (ModelDefinitionNode, ModelEuAxisCoord)):
        for aspect in definitionNode.aspectsCovered():
            aspectsCovered.add(aspect)
            if (aspect in uncoverableAspects or
                (isinstance(aspect, QName) and modelTable.aspectModel == 'non-dimensional')):
                modelXbrl.error("xbrlte:axisAspectModelMismatch",
                    _("%(definitionNode)s %(xlinkLabel)s, aspect model %(aspectModel)s, aspect %(aspect)s not allowed"),
                    modelObject=modelTable, definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel, aspectModel=modelTable.aspectModel,
                    aspect=str(aspect) if isinstance(aspect,QName) else Aspect.label[aspect])
            hasCoveredAspect = True
            if aspect in modelTable.priorAspectAxisDisposition:
                otherAxisDisposition, otherDefinitionNode = modelTable.priorAspectAxisDisposition[aspect]
                if tblAxisDisposition != otherAxisDisposition and aspect != Aspect.DIMENSIONS:
                    modelXbrl.error("xbrlte:aspectClashBetweenBreakdowns",
                        _("%(definitionNode)s %(xlinkLabel)s, aspect %(aspect)s defined on axes of disposition %(axisDisposition)s and %(axisDisposition2)s"),
                        modelObject=(modelTable, definitionNode, otherDefinitionNode), definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel, 
                        axisDisposition=tblAxisDisposition, axisDisposition2=otherAxisDisposition,
                        aspect=str(aspect) if isinstance(aspect,QName) else Aspect.label[aspect])
            else:
                modelTable.priorAspectAxisDisposition[aspect] = (tblAxisDisposition, definitionNode)
        ruleSetChildren = XmlUtil.children(definitionNode, definitionNode.namespaceURI, "ruleSet")
        if definitionNode.isMerged:
            if ruleSetChildren:
                modelXbrl.error("xbrlte:mergedRuleNodeWithTaggedRuleSet",
                    _("Merged %(definitionNode)s %(xlinkLabel)s has tagged rule set(s)"),
                    modelObject=[modelTable, definitionNode] + ruleSetChildren, 
                    definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel)
            labelRels = modelXbrl.relationshipSet(XbrlConst.elementLabel).fromModelObject(definitionNode)
            if labelRels:
                modelXbrl.error("xbrlte:mergedRuleNodeWithLabel",
                    _("Merged %(definitionNode)s %(xlinkLabel)s has label(s)"),
                    modelObject=[modelTable, definitionNode] + [r.toModelObject for r in labelRels], 
                    definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel)
            if not definitionNode.isAbstract:
                modelXbrl.error("xbrlte:nonAbstractMergedRuleNode",
                    _("Merged %(definitionNode)s %(xlinkLabel)s is not abstract"),
                    modelObject=(modelTable, definitionNode), definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel)
    if isinstance(definitionNode, ModelRuleDefinitionNode):
        tagConstraintSets = {}
        otherConstraintSet = None
        # must look at xml constructs for duplicates
        for ruleSet in XmlUtil.children(definitionNode, definitionNode.namespaceURI, "ruleSet"):
            tag = ruleSet.tagName
            if tag is not None: # named constraint sets only
                for aspect in ruleSet.aspectsCovered():
                    if aspect != Aspect.DIMENSIONS:
                        modelTable.aspectsInTaggedConstraintSets.add(aspect)
            if tag in tagConstraintSets:
                modelXbrl.error("xbrlte:duplicateTag",
                    _("%(definitionNode)s %(xlinkLabel)s duplicate rule set tags %(tag)s"),
                    modelObject=(modelTable, definitionNode, tagConstraintSets[tag], ruleSet), 
                    definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel, tag=tag)
            else:
                tagConstraintSets[tag] = ruleSet
        for tag, constraintSet in definitionNode.constraintSets.items():
            if otherConstraintSet is None:
                otherConstraintSet = constraintSet
            elif otherConstraintSet.aspectsCovered() != constraintSet.aspectsCovered():
                modelXbrl.error("xbrlte:constraintSetAspectMismatch",
                    _("%(definitionNode)s %(xlinkLabel)s constraint set mismatches between %(tag1)s and %(tag2)s in constraints %(aspects)s"),
                    modelObject=(modelTable, definitionNode, otherConstraintSet, constraintSet), 
                    definitionNode=definitionNode.localName, xlinkLabel=definitionNode.xlinkLabel, 
                    tag1=otherConstraintSet.tagName, tag2=constraintSet.tagName,
                    aspects=", ".join(aspectStr(aspect) 
                                      for aspect in otherConstraintSet.aspectsCovered() ^ constraintSet.aspectsCovered()
                                      if aspect != Aspect.DIMENSIONS))
    if isinstance(definitionNode, ModelDimensionRelationshipDefinitionNode):
        hasCoveredAspect = True
        if modelTable.aspectModel == 'non-dimensional':
            modelXbrl.error("xbrlte:axisAspectModelMismatch",
                _("DimensionRelationship axis %(xlinkLabel)s can't be used in non-dimensional aspect model"),
                modelObject=(modelTable,definitionNode), xlinkLabel=definitionNode.xlinkLabel)
    definitionNodeHasChild = False
    for axisSubtreeRel in modelXbrl.relationshipSet((XbrlConst.tableBreakdownTree, XbrlConst.tableBreakdownTreeMMDD, XbrlConst.tableBreakdownTree201305, XbrlConst.tableDefinitionNodeSubtree, XbrlConst.tableDefinitionNodeSubtreeMMDD, XbrlConst.tableDefinitionNodeSubtree201305, XbrlConst.tableDefinitionNodeSubtree201301, XbrlConst.tableAxisSubtree2011)).fromModelObject(definitionNode):
        if checkBreakdownDefinitionNode(modelXbrl, modelTable, axisSubtreeRel, tblAxisDisposition, uncoverableAspects, aspectsCovered):
            hasCoveredAspect = True # something below was covering
        definitionNodeHasChild = True
    if isinstance(definitionNode, ModelFilterDefinitionNode):
        for aspect in definitionNode.aspectsCovered():
            if isinstance(aspect, QName): # dimension aspect
                concept = modelXbrl.qnameConcepts.get(aspect)
                if concept is None or not concept.isDimensionItem:
                    modelXbrl.error("xbrlte:invalidDimensionQNameOnAspectNode",
                        _("Aspect node %(xlinkLabel)s dimensional aspect %(dimension)s is not a dimension"),
                        modelObject=(modelTable,definitionNode), xlinkLabel=definitionNode.xlinkLabel, dimension=aspect)
    
    if not definitionNodeHasChild:
        if (definitionNode.namespaceURI in ("http://www.eurofiling.info/2010/rendering", "http://xbrl.org/2011/table") 
            and not hasCoveredAspect):
            modelXbrl.error("xbrlte:aspectValueNotDefinedByOrdinate",
                _("%(definitionNode)s %(xlinkLabel)s does not define an aspect"),
                modelObject=(modelTable,definitionNode), xlinkLabel=definitionNode.xlinkLabel, definitionNode=definitionNode.localName)
        if (isinstance(definitionNode, ModelClosedDefinitionNode) and
            definitionNode.isAbstract):
            modelXbrl.error("xbrlte:abstractRuleNodeNoChildren",
                _("Abstract %(definitionNode)s %(xlinkLabel)s has no children"),
                modelObject=(modelTable,definitionNode), xlinkLabel=definitionNode.xlinkLabel, definitionNode=definitionNode.localName)
    return hasCoveredAspect
Пример #7
0
 def doObject(self, fObj, fromRel, visited):
     if fObj is None:
         return
     if isinstance(fObj, ModelAssertionSet):
         for modelRel in self.modelXbrl.relationshipSet(
                 XbrlConst.assertionSet).fromModelObject(fObj):
             self.doObject(modelRel.toModelObject, modelRel, visited)
     elif isinstance(
             fObj,
         (ModelValueAssertion, ModelExistenceAssertion, ModelFormula)):
         for arcrole in (XbrlConst.elementLabel,
                         XbrlConst.assertionSatisfiedMessage,
                         XbrlConst.assertionUnsatisfiedMessage,
                         XbrlConst.assertionUnsatisfiedSeverity):
             for modelRel in self.modelXbrl.relationshipSet(
                     arcrole).fromModelObject(fObj):
                 self.doObject(modelRel.toModelObject, modelRel, visited)
         if isinstance(fObj, ModelFormula):
             self.checkProg(fObj, "value", "valueProg")
             aspectProgs = getattr(fObj, "aspectProgs", {})
             for aspect, prog in aspectProgs.items():
                 self.checkProg(fObj, aspectStr(aspect), prog)
         for arcrole in (XbrlConst.variableSetFilter, XbrlConst.variableSet,
                         XbrlConst.variableSetPrecondition):
             for modelRel in self.modelXbrl.relationshipSet(
                     arcrole).fromModelObject(fObj):
                 self.doObject(modelRel.toModelObject, modelRel, visited)
         if isinstance(fObj,
                       (ModelValueAssertion, ModelExistenceAssertion)):
             self.checkProg(fObj, "test", "testProg")
     elif isinstance(fObj, ModelConsistencyAssertion):
         if fObj.hasProportionalAcceptanceRadius:
             self.checkProg(fObj, "proportionalAcceptanceRadius",
                            "radiusProg")
         elif fObj.hasProportionalAcceptanceRadius:
             self.checkProg(fObj, "absoluteAcceptanceRadius", "radiusProg")
         for arcrole in (XbrlConst.elementLabel,
                         XbrlConst.assertionSatisfiedMessage,
                         XbrlConst.assertionUnsatisfiedMessage):
             for modelRel in self.modelXbrl.relationshipSet(
                     arcrole).fromModelObject(fObj):
                 self.doObject(modelRel.toModelObject, modelRel, visited)
         for modelRel in self.modelXbrl.relationshipSet(
                 XbrlConst.consistencyAssertionFormula).fromModelObject(
                     fObj):
             self.doObject(modelRel.toModelObject, modelRel, visited)
     elif isinstance(fObj, ModelFactVariable) and fromRel is not None:
         self.checkProg(fObj, "fallbackValue", "fallbackValueProg")
         for modelRel in self.modelXbrl.relationshipSet(
                 XbrlConst.variableFilter).fromModelObject(fObj):
             self.doObject(modelRel.toModelObject, modelRel, visited)
     elif isinstance(fObj, ModelGeneralVariable) and fromRel is not None:
         self.checkProg(fObj, "select", "selectProg")
     elif isinstance(fObj, ModelParameter):
         self.checkProg(fObj, "select", "selectProg")
     elif isinstance(fObj, ModelFilter):
         if isinstance(fObj, ModelConceptName):
             for i, prog in enumerate(
                     getattr(fObj, "qnameExpressionProgs", ())):
                 self.checkProg(fObj, "qnameExpression" + str(i + 1), prog)
         elif isinstance(fObj, ModelExplicitDimension):
             for i, memberProg in enumerate(getattr(fObj, "memberProgs",
                                                    ())):
                 if memberProg.qnameExprProg:
                     self.checkProg(fObj,
                                    "member{}qnameExpression".format(i + 1),
                                    memberProg.qnameExprProg)
         elif isinstance(
                 fObj, ModelTypedDimension
         ):  # this is a ModelTestFilter not same as genera/unit/period
             self.checkProg(fObj, "qnameExpression",
                            "dimQnameExpressionProg")
         elif isinstance(fObj, ModelTestFilter):
             self.checkProg(fObj, "test", "testProg")
         elif isinstance(fObj, ModelSingleMeasure):
             self.checkProg(fObj, "qnameExpression", "qnameExpressionProg")
         elif isinstance(fObj, ModelEntitySpecificIdentifier):
             self.checkProg(fObj, "scheme", "schemeProg")
             self.checkProg(fObj, "value", "valueProg")
         elif isinstance(fObj, ModelEntityScheme):
             self.checkProg(fObj, "scheme", "schemeProg")
         elif isinstance(fObj, (ModelAncestorFilter, ModelParentFilter)):
             self.checkProg(fObj, "qnameExpression", "qnameExpressionProg")
         elif isinstance(fObj, ModelAspectCover):
             for mode in ("include", "exclude"):
                 for i, dimProg in enumerate(
                         getattr(fObj, "{}dDimQnameProgs", ())):
                     self.checkProg(
                         fObj,
                         "{}Dimension{}QnameExpression".format(mode, i + 1),
                         dimProg)
         elif isinstance(fObj, ModelConceptRelation):
             self.checkProg(fObj, "qnameExpression",
                            "sourceQnameExpressionProg")
             self.checkProg(fObj, "linkroleExpression",
                            "linkroleQnameExpressionProg")
             self.checkProg(fObj, "linknameExpression",
                            "linknameQnameExpressionProg")
             self.checkProg(fObj, "arcroleExpression",
                            "arcroleQnameExpressionProg")
             self.checkProg(fObj, "arcnameExpression",
                            "arcnameQnameExpressionProg")
             self.checkProg(fObj, "test", "testExpressionProg")
     elif isinstance(fObj, ModelMessage):
         if isinstance(fObj, ModelConceptName):
             for i, prog in enumerate(getattr(fObj, "expressionProgs", ())):
                 self.checkProg(fObj, "expression" + str(i + 1), prog)
     elif isinstance(fObj, ModelCustomFunctionImplementation):
         self.checkProg(fObj, "output", "outputProg")
         for i, prog in enumerate(getattr(fObj, "stepProgs", ())):
             self.checkProg(fObj, "step" + str(i + 1), prog)
Пример #8
0
 def filterFacts(self, facts):
     modelXbrl = self.sCtx.modelXbrl
     # process with bindings and this node
     for i, aspectAxis in enumerate(self.aspectAxisTuples):
         aspect, hsAxis = aspectAxis
         # value is an astHyperspaceAxis
         if hsAxis.restriction:
             restriction = evaluate(hsAxis.restriction, self.sCtx, value=True)
             if aspect == Aspect.CONCEPT:
                 aspectQualifiedFacts = [modelXbrl.factsByQname[qn]
                                         for qn in restriction
                                         if isinstance(qn, QName)]
                 facts = facts & set.union(*aspectQualifiedFacts) if aspectQualifiedFacts else set()
             elif aspect == Aspect.PERIOD:
                 facts = set(f for f in facts if isPeriodEqualTo(f, restriction))
             elif aspect == Aspect.ENTITY_IDENTIFIER:
                 facts = set(f for f in facts if isEntityIdentifierEqualTo(f, restriction))
             elif isinstance(aspect, QName):
                 if self.sCtx.dimensionIsExplicit.get(aspect):
                     # explicit dim facts (value None will match the default member)
                     aspectQualifiedFacts = []
                     for qn in restriction:
                         if self.isBalancingBinding: # complement dimension for aggregation balancing binding
                             if isinstance(qn, QName) or qn is NONDEFAULT:
                                 qn = DEFAULT
                             else:
                                 qn = NONDEFAULT
                         if qn is NONE:
                             qn = DEFAULT
                         elif not (isinstance(qn, QName) or qn is DEFAULT or qn is NONDEFAULT):
                             continue
                         aspectQualifiedFacts.append(modelXbrl.factsByDimMemQname(aspect, qn))
                     facts = facts & set.union(*aspectQualifiedFacts) if aspectQualifiedFacts else set()
                 else:
                     facts = facts & set(fact 
                                         for fact in facts
                                         for typedDimValue in hsAxis.restriction
                                         if typedDimTest(aspect, typedDimValue, fact))
         if hsAxis.whereExpr and facts:  # process where against facts passing restriction
             whereMatchedFacts = set()
             asVars = set()
             for fact in facts:
                 for asAspectAxis in self.aspectAxisTuples[0:i+1]:
                     asAspect, asHsAxis = asAspectAxis
                     if asHsAxis.asVariableName:
                         self.sCtx.localVariables[asHsAxis.asVariableName] = factAspectValue(fact, asAspect)
                         asVars.add(asHsAxis.asVariableName)
                 self.sCtx.localVariables["item"] = fact
                 if evaluate(hsAxis.whereExpr, self.sCtx) ^ self.isBalancingBinding:
                     whereMatchedFacts.add(fact)
             del self.sCtx.localVariables["item"]
             for asVar in asVars:
                 del self.sCtx.localVariables[asVar]
             facts = whereMatchedFacts
         if self.sCtx.formulaOptions.traceVariableFilterWinnowing:
             self.sCtx.modelXbrl.info("sphinx:trace",
                  _("Hyperspace %(variable)s: %(filter)s filter passes %(factCount)s facts"), 
                  sourceFileLine=self.node.sourceFileLine, variable=str(self.node), filter=aspectStr(aspect), factCount=len(facts))
     if self.node.isClosed: # winnow out non-qualified dimension breakdowns
         facts = facts - set(fact
                             for fact in facts
                             if fact.dimAspects - self.aspectsQualified )
         if self.sCtx.formulaOptions.traceVariableFilterWinnowing:
             self.sCtx.modelXbrl.info("sphinx:trace",
                  _("Hyperspace %(variable)s: closed selection filter passes %(factCount)s facts"), 
                  sourceFileLine=self.node.sourceFileLine, variable=str(self.node), factCount=len(facts))
     return facts
Пример #9
0
 def filterFacts(self, facts):
     modelXbrl = self.sCtx.modelXbrl
     # process with bindings and this node
     for i, aspectAxis in enumerate(self.aspectAxisTuples):
         aspect, hsAxis = aspectAxis
         # value is an astHyperspaceAxis
         if hsAxis.restriction:
             restriction = evaluate(hsAxis.restriction,
                                    self.sCtx,
                                    value=True)
             if aspect == Aspect.CONCEPT:
                 aspectQualifiedFacts = [
                     modelXbrl.factsByQname[qn] for qn in restriction
                     if isinstance(qn, QName)
                 ]
                 facts = facts & set.union(
                     *aspectQualifiedFacts
                 ) if aspectQualifiedFacts else set()
             elif aspect == Aspect.PERIOD:
                 facts = set(f for f in facts
                             if isPeriodEqualTo(f, restriction))
             elif aspect == Aspect.ENTITY_IDENTIFIER:
                 facts = set(f for f in facts
                             if isEntityIdentifierEqualTo(f, restriction))
             elif isinstance(aspect, QName):
                 if self.sCtx.dimensionIsExplicit.get(aspect):
                     # explicit dim facts (value None will match the default member)
                     aspectQualifiedFacts = []
                     for qn in restriction:
                         if self.isBalancingBinding:  # complement dimension for aggregation balancing binding
                             if isinstance(qn, QName) or qn is NONDEFAULT:
                                 qn = DEFAULT
                             else:
                                 qn = NONDEFAULT
                         if qn is NONE:
                             qn = DEFAULT
                         elif not (isinstance(qn, QName) or qn is DEFAULT
                                   or qn is NONDEFAULT):
                             continue
                         aspectQualifiedFacts.append(
                             modelXbrl.factsByDimMemQname(aspect, qn))
                     facts = facts & set.union(
                         *aspectQualifiedFacts
                     ) if aspectQualifiedFacts else set()
                 else:
                     facts = facts & set(
                         fact for fact in facts
                         for typedDimValue in hsAxis.restriction
                         if typedDimTest(aspect, typedDimValue, fact))
         if hsAxis.whereExpr and facts:  # process where against facts passing restriction
             whereMatchedFacts = set()
             asVars = set()
             for fact in facts:
                 for asAspectAxis in self.aspectAxisTuples[0:i + 1]:
                     asAspect, asHsAxis = asAspectAxis
                     if asHsAxis.asVariableName:
                         self.sCtx.localVariables[
                             asHsAxis.asVariableName] = factAspectValue(
                                 fact, asAspect)
                         asVars.add(asHsAxis.asVariableName)
                 self.sCtx.localVariables["item"] = fact
                 if evaluate(hsAxis.whereExpr,
                             self.sCtx) ^ self.isBalancingBinding:
                     whereMatchedFacts.add(fact)
             del self.sCtx.localVariables["item"]
             for asVar in asVars:
                 del self.sCtx.localVariables[asVar]
             facts = whereMatchedFacts
         if self.sCtx.formulaOptions.traceVariableFilterWinnowing:
             self.sCtx.modelXbrl.info(
                 "sphinx:trace",
                 _("Hyperspace %(variable)s: %(filter)s filter passes %(factCount)s facts"
                   ),
                 sourceFileLine=self.node.sourceFileLine,
                 variable=str(self.node),
                 filter=aspectStr(aspect),
                 factCount=len(facts))
     if self.node.isClosed:  # winnow out non-qualified dimension breakdowns
         facts = facts - set(fact for fact in facts
                             if fact.dimAspects - self.aspectsQualified)
         if self.sCtx.formulaOptions.traceVariableFilterWinnowing:
             self.sCtx.modelXbrl.info(
                 "sphinx:trace",
                 _("Hyperspace %(variable)s: closed selection filter passes %(factCount)s facts"
                   ),
                 sourceFileLine=self.node.sourceFileLine,
                 variable=str(self.node),
                 factCount=len(facts))
     return facts
Пример #10
0
 def view(self, viewTblELR=None):
     if viewTblELR is not None:
         tblELRs = (viewTblELR,)
     else:
         tblELRs = self.modelXbrl.relationshipSet("Table-rendering").linkRoleUris
         
     if self.type == XML:
         self.tblElt.append(etree.Comment("Entry point file: {0}".format(self.modelXbrl.modelDocument.basename)))
     
     for tblELR in tblELRs:
         self.zOrdinateChoices = {}
         
         for discriminator in range(1, 65535):
             tblAxisRelSet, xTopStructuralNode, yTopStructuralNode, zTopStructuralNode = resolveAxesStructure(self, tblELR)
             
             self.zStrNodesWithChoices = []
             if tblAxisRelSet and self.tblElt is not None:
                 tableLabel = (self.modelTable.genLabel(lang=self.lang, strip=True) or  # use table label, if any 
                               self.roledefinition)
                 if self.type == HTML: # table on each Z
                     # each Z is a separate table in the outer table
                     zTableRow = etree.SubElement(self.tblElt, "{http://www.w3.org/1999/xhtml}tr")
                     zRowCell = etree.SubElement(zTableRow, "{http://www.w3.org/1999/xhtml}td")
                     zCellTable = etree.SubElement(zRowCell, "{http://www.w3.org/1999/xhtml}table",
                                                   attrib={"border":"1", "cellspacing":"0", "cellpadding":"4", "style":"font-size:8pt;"})
                     self.rowElts = [etree.SubElement(zCellTable, "{http://www.w3.org/1999/xhtml}tr")
                                     for r in range(self.dataFirstRow + self.dataRows - 1)]
                     etree.SubElement(self.rowElts[0], "{http://www.w3.org/1999/xhtml}th",
                                      attrib={"class":"tableHdr",
                                              "style":"max-width:100em;",
                                              "colspan": str(self.dataFirstCol - 1),
                                              "rowspan": str(self.dataFirstRow - 1)}
                                      ).text = tableLabel
                 elif self.type == XML:
                     self.structuralNodeModelElements = []
                     if discriminator == 1:
                         tableSetElt = etree.SubElement(self.tblElt, tableModelQName("tableSet"))
                         tableSetElt.append(etree.Comment("TableSet linkbase file: {0}, line {1}".format(self.modelTable.modelDocument.basename, self.modelTable.sourceline)))
                         tableSetElt.append(etree.Comment("TableSet namespace: {0}".format(self.modelTable.namespaceURI)))
                         tableSetElt.append(etree.Comment("TableSet linkrole: {0}".format(tblELR)))
                         self.zHdrsElt = etree.SubElement(tableSetElt, tableModelQName("headers"))
                         zAspects = defaultdict(set)
                         self.zAxis(1, zTopStructuralNode, zAspects, True)
                     tableElt = etree.SubElement(tableSetElt, tableModelQName("table"),
                                                 attrib={"label": tableLabel})
                     hdrsElts = dict((disposition,
                                      etree.SubElement(tableElt, tableModelQName("headers"),
                                                       attrib={"disposition": disposition}))
                                     for disposition in ("y", "x"))
                     self.zHdrsElt = hdrsElts["y"]  # z-comments go before y subelement of tableElt
                     # new y,x cells on each Z combination
                     if yTopStructuralNode.childStructuralNodes: # no row header element if no rows
                         self.rowHdrElts = [etree.SubElement(hdrsElts["y"], tableModelQName("header"))
                                            for i in range(self.rowHdrCols - 1 + len(self.rowHdrNonStdRoles))] # self.rowHdrDocCol + self.rowHdrCodeCol)]
                     else:
                         hdrsElts["y"].append(etree.Comment("no rows in this table"))
                     if xTopStructuralNode.childStructuralNodes: # no col header element if no cols
                         self.colHdrElts = [etree.SubElement(hdrsElts["x"], tableModelQName("header"))
                                            for i in range(self.colHdrRows - 1 + len(self.colHdrNonStdRoles))] # self.colHdrDocRow + self.colHdrCodeRow)]
                     else:
                         hdrsElts["x"].append(etree.Comment("no columns in this table"))
                     self.zCells = etree.SubElement(tableElt, tableModelQName("cells"),
                                                       attrib={"disposition": "z"})
                     self.yCells = etree.SubElement(self.zCells, tableModelQName("cells"),
                                                       attrib={"disposition": "y"})
                     ''' move into body cells, for entry row-by-row
                     self.xCells = etree.SubElement(self.yCells, tableModelQName("cells"),
                                                       attrib={"disposition": "x"})
                     '''
                 # rows/cols only on firstTime for infoset XML, but on each time for xhtml
                 zAspects = defaultdict(set)
                 self.zAxis(1, zTopStructuralNode, zAspects, False)
                 xStructuralNodes = []
                 if self.type == HTML or (xTopStructuralNode.childStructuralNodes):
                     self.xAxis(self.dataFirstCol, self.colHdrTopRow, self.colHdrTopRow + self.colHdrRows - 1, 
                                xTopStructuralNode, xStructuralNodes, self.xAxisChildrenFirst.get(), True, True)
                 if self.type == HTML: # table/tr goes by row
                     self.yAxisByRow(1, self.dataFirstRow,
                                     yTopStructuralNode, self.yAxisChildrenFirst.get(), True, True)
                 elif self.type == XML: # infoset goes by col of row header
                     if yTopStructuralNode.childStructuralNodes: # no row header element if no rows
                         self.yAxisByCol(1, self.dataFirstRow,
                                         yTopStructuralNode, self.yAxisChildrenFirst.get(), True, True)
                     for structuralNode,modelElt in self.structuralNodeModelElements: # must do after elements are all arragned
                         modelElt.addprevious(etree.Comment("{0}: label {1}, file {2}, line {3}"
                                                       .format(structuralNode._definitionNode.localName,
                                                               structuralNode._definitionNode.xlinkLabel,
                                                               structuralNode._definitionNode.modelDocument.basename, 
                                                               structuralNode._definitionNode.sourceline)))
                         if structuralNode._definitionNode.get('value'):
                             modelElt.addprevious(etree.Comment("   @value {0}".format(structuralNode._definitionNode.get('value'))))
                         for aspect in sorted(structuralNode.aspectsCovered(), key=lambda a: aspectStr(a)):
                             if structuralNode.hasAspect(aspect) and aspect != Aspect.DIMENSIONS:
                                 aspectValue = structuralNode.aspectValue(aspect)
                                 if aspectValue is None: aspectValue = "(bound dynamically)"
                                 modelElt.addprevious(etree.Comment("   aspect {0}: {1}".format(aspectStr(aspect), aspectValue)))
                         for varName, varValue in structuralNode.variables.items():
                                 modelElt.addprevious(etree.Comment("   variable ${0}: {1}".format(varName, varValue)))
                         
                 self.bodyCells(self.dataFirstRow, yTopStructuralNode, xStructuralNodes, zAspects, self.yAxisChildrenFirst.get())
             # find next choice structural node
             moreDiscriminators = False
             for zStrNodeWithChoices in self.zStrNodesWithChoices:
                 currentIndex = zStrNodeWithChoices.choiceNodeIndex + 1
                 if currentIndex < len(zStrNodeWithChoices.choiceStructuralNodes):
                     zStrNodeWithChoices.choiceNodeIndex = currentIndex
                     self.zOrdinateChoices[zStrNodeWithChoices._definitionNode] = currentIndex
                     moreDiscriminators = True
                     break
                 else:
                     zStrNodeWithChoices.choiceNodeIndex = 0
                     self.zOrdinateChoices[zStrNodeWithChoices._definitionNode] = 0
                     # continue incrementing next outermore z choices index
             if not moreDiscriminators:
                 break
Пример #11
0
 def yAxisByCol(self, leftCol, row, yParentStructuralNode, childrenFirst, renderNow, atTop):
     if yParentStructuralNode is not None:
         nestedBottomRow = row
         for yStructuralNode in yParentStructuralNode.childStructuralNodes:
             nestRow, nextRow = self.yAxisByCol(leftCol + 1, row, yStructuralNode,  # nested items before totals
                                                childrenFirst, childrenFirst, False)
             isAbstract = (yStructuralNode.isAbstract or 
                           (yStructuralNode.childStructuralNodes and
                            not isinstance(yStructuralNode.definitionNode, (ModelClosedDefinitionNode, ModelEuAxisCoord))))
             isNonAbstract = not isAbstract
             label = yStructuralNode.header(lang=self.lang,
                                            returnGenLabel=isinstance(yStructuralNode.definitionNode, (ModelClosedDefinitionNode, ModelEuAxisCoord)))
             topRow = row
             if childrenFirst and isNonAbstract:
                 row = nextRow
             #print ( "thisCol {0} leftCol {1} rightCol {2} topRow{3} renderNow {4} label {5}".format(thisCol, leftCol, rightCol, topRow, renderNow, label))
             if renderNow:
                 rowspan= nestRow - row + 1
                 cellElt = etree.Element(tableModelQName("cell"),
                                         attrib={"span": str(rowspan)} if rowspan > 1 else None)
                 elt = etree.SubElement(cellElt, tableModelQName("label"))
                 elt.text = label
                 self.rowHdrElts[leftCol - 1].append(cellElt)
                 self.structuralNodeModelElements.append((yStructuralNode, cellElt))
                 for aspect in sorted(yStructuralNode.aspectsCovered(), key=lambda a: aspectStr(a)):
                     if yStructuralNode.hasAspect(aspect) and aspect != Aspect.DIMENSIONS:
                         aspectValue = yStructuralNode.aspectValue(aspect)
                         if aspectValue is None: aspectValue = "(bound dynamically)"
                         elt = etree.SubElement(cellElt, tableModelQName("constraint"))
                         etree.SubElement(elt, tableModelQName("aspect")
                                          ).text = aspectStr(aspect)
                         etree.SubElement(elt, tableModelQName("value")
                                          ).text = addQnameValue(self.xmlDoc, aspectValue)
                 for rollUpCol in range(leftCol, self.rowHdrCols - 1):
                     rollUpElt = etree.Element(tableModelQName("cell"),
                                               attrib={"rollup":"true"})
                     self.rowHdrElts[rollUpCol].append(rollUpElt)
                 if isNonAbstract:
                     cellElt = etree.Element(tableModelQName("cell"),
                                             attrib={"span": str(rowspan)} if rowspan > 1 else None)
                     for i, role in enumerate(self.rowHdrNonStdRoles):
                         labelElt = etree.SubElement(cellElt, tableModelQName("label"),
                                                     attrib={"role":role,
                                                             "lang":self.lang})
                         labelElt.text = yStructuralNode.header(role=role, lang=self.lang)
                     self.rowHdrElts[self.rowHdrCols - 1 + i].append(cellElt)
                     for aspect in sorted(yStructuralNode.aspectsCovered(), key=lambda a: aspectStr(a)):
                         if yStructuralNode.hasAspect(aspect) and aspect != Aspect.DIMENSIONS:
                             aspectValue = yStructuralNode.aspectValue(aspect)
                             if aspectValue is None: aspectValue = "(bound dynamically)"
                             elt = etree.SubElement(cellElt, tableModelQName("constraint"))
                             etree.SubElement(elt, tableModelQName("aspect")
                                              ).text = aspectStr(aspect)
                             etree.SubElement(elt, tableModelQName("value")
                                              ).text = addQnameValue(self.xmlDoc, aspectValue)
                     '''
                     if self.rowHdrDocCol:
                         labelElt = etree.SubElement(cellElt, tableModelQName("label"),
                                                     attrib={"span": str(rowspan)} if rowspan > 1 else None)
                         elt.text = yStructuralNode.header(role="http://www.xbrl.org/2008/role/documentation",
                                                    lang=self.lang)
                         self.rowHdrElts[self.rowHdrCols - 1].append(elt)
                     if self.rowHdrCodeCol:
                         elt = etree.Element(tableModelQName("label"),
                                             attrib={"span": str(rowspan)} if rowspan > 1 else None)
                         elt.text = yStructuralNode.header(role="http://www.eurofiling.info/role/2010/coordinate-code",
                                                    lang=self.lang)
                         self.rowHdrElts[self.rowHdrCols - 1 + self.rowHdrDocCol].append(elt)
                     '''
             if isNonAbstract:
                 row += 1
             elif childrenFirst:
                 row = nextRow
             if nestRow > nestedBottomRow:
                 nestedBottomRow = nestRow + (isNonAbstract and not childrenFirst)
             if row > nestedBottomRow:
                 nestedBottomRow = row
             #if renderNow and not childrenFirst:
             #    dummy, row = self.yAxis(leftCol + 1, row, yStructuralNode, childrenFirst, True, False) # render on this pass
             if not childrenFirst:
                 dummy, row = self.yAxisByCol(leftCol + 1, row, yStructuralNode, childrenFirst, renderNow, False) # render on this pass
         return (nestedBottomRow, row)
Пример #12
0
 def xAxis(self, leftCol, topRow, rowBelow, xParentStructuralNode, xStructuralNodes, childrenFirst, renderNow, atTop):
     if xParentStructuralNode is not None:
         parentRow = rowBelow
         noDescendants = True
         rightCol = leftCol
         widthToSpanParent = 0
         sideBorder = not xStructuralNodes
         for xStructuralNode in xParentStructuralNode.childStructuralNodes:
             noDescendants = False
             rightCol, row, width, leafNode = self.xAxis(leftCol, topRow + 1, rowBelow, xStructuralNode, xStructuralNodes, # nested items before totals
                                                         childrenFirst, childrenFirst, False)
             if row - 1 < parentRow:
                 parentRow = row - 1
             #if not leafNode: 
             #    rightCol -= 1
             nonAbstract = not xStructuralNode.isAbstract
             if nonAbstract:
                 width += 100 # width for this label
             widthToSpanParent += width
             label = xStructuralNode.header(lang=self.lang,
                                            returnGenLabel=isinstance(xStructuralNode.definitionNode, (ModelClosedDefinitionNode, ModelEuAxisCoord)))
             if childrenFirst:
                 thisCol = rightCol
             else:
                 thisCol = leftCol
             #print ( "thisCol {0} leftCol {1} rightCol {2} topRow{3} renderNow {4} label {5}".format(thisCol, leftCol, rightCol, topRow, renderNow, label))
             if renderNow:
                 columnspan = rightCol - leftCol + (1 if nonAbstract else 0)
                 if self.type == HTML:
                     if rightCol == self.dataFirstCol + self.dataCols - 1:
                         edgeBorder = "border-right:.5pt solid windowtext;"
                     else:
                         edgeBorder = ""
                     attrib = {"class":"xAxisHdr",
                               "style":"text-align:center;max-width:{0}pt;{1}".format(width,edgeBorder)}
                     if columnspan > 1:
                         attrib["colspan"] = str(columnspan)
                     if leafNode and row > topRow:
                         attrib["rowspan"] = str(row - topRow + 1)
                     elt = etree.Element("{http://www.w3.org/1999/xhtml}th",
                                         attrib=attrib)
                     self.rowElts[topRow-1].insert(leftCol,elt)
                 elif self.type == XML:
                     cellElt = etree.Element(tableModelQName("cell"),
                                         attrib={"span": str(columnspan)} if columnspan > 1 else None)
                     self.colHdrElts[topRow - self.colHdrTopRow].insert(leftCol,cellElt)
                     self.structuralNodeModelElements.append((xStructuralNode, cellElt))
                     elt = etree.SubElement(cellElt, tableModelQName("label"))
                     if nonAbstract or (leafNode and row > topRow):
                         for rollUpCol in range(topRow - self.colHdrTopRow + 1, self.colHdrRows - 1):
                             rollUpElt = etree.Element(tableModelQName("label"),
                                                       attrib={"rollup":"true"})
                             if childrenFirst:
                                 self.colHdrElts[rollUpCol].append(rollUpElt)
                             else:
                                 self.colHdrElts[rollUpCol].insert(leftCol,rollUpElt)
                     for i, role in enumerate(self.colHdrNonStdRoles):
                         etree.SubElement(cellElt, tableModelQName("label"), 
                                          attrib={"role": role,
                                                  "lang": self.lang}
                                          ).text = xStructuralNode.header(
                                                role=role, lang=self.lang)
                     for aspect in sorted(xStructuralNode.aspectsCovered(), key=lambda a: aspectStr(a)):
                         if xStructuralNode.hasAspect(aspect) and aspect != Aspect.DIMENSIONS:
                             aspectValue = xStructuralNode.aspectValue(aspect)
                             if aspectValue is None: aspectValue = "(bound dynamically)"
                             aspElt = etree.SubElement(cellElt, tableModelQName("constraint"))
                             etree.SubElement(aspElt, tableModelQName("aspect")
                                              ).text = aspectStr(aspect)
                             etree.SubElement(aspElt, tableModelQName("value")
                                              ).text = addQnameValue(self.xmlDoc, aspectValue)
                 elt.text = label or "\u00A0" #produces &nbsp;
                 if nonAbstract:
                     if columnspan > 1 and rowBelow > topRow:   # add spanned left leg portion one row down
                         if self.type == HTML:
                             attrib= {"class":"xAxisSpanLeg",
                                      "rowspan": str(rowBelow - row)}
                             if edgeBorder:
                                 attrib["style"] = edgeBorder
                             elt = etree.Element("{http://www.w3.org/1999/xhtml}th",
                                                 attrib=attrib)
                             elt.text = "\u00A0"
                             if childrenFirst:
                                 self.rowElts[topRow].append(elt)
                             else:
                                 self.rowElts[topRow].insert(leftCol,elt)
                     if self.type == HTML:
                         for i, role in enumerate(self.colHdrNonStdRoles):
                             elt = etree.Element("{http://www.w3.org/1999/xhtml}th",
                                                 attrib={"class":"xAxisHdr",
                                                         "style":"text-align:center;max-width:100pt;{0}".format(edgeBorder)})
                             self.rowElts[self.dataFirstRow - 1 - len(self.colHdrNonStdRoles) + i].insert(thisCol,elt)
                             elt.text = xStructuralNode.header(role=role, lang=self.lang) or "\u00A0"
                     '''
                     if self.colHdrDocRow:
                         doc = xStructuralNode.header(role="http://www.xbrl.org/2008/role/documentation", lang=self.lang)
                         if self.type == HTML:
                             elt = etree.Element("{http://www.w3.org/1999/xhtml}th",
                                                 attrib={"class":"xAxisHdr",
                                                         "style":"text-align:center;max-width:100pt;{0}".format(edgeBorder)})
                             self.rowElts[self.dataFirstRow - 2 - self.rowHdrCodeCol].insert(thisCol,elt)
                         elif self.type == XML:
                             elt = etree.Element(tableModelQName("label"))
                             self.colHdrElts[self.colHdrRows - 1].insert(thisCol,elt)
                         elt.text = doc or "\u00A0"
                     if self.colHdrCodeRow:
                         code = xStructuralNode.header(role="http://www.eurofiling.info/role/2010/coordinate-code")
                         if self.type == HTML:
                             elt = etree.Element("{http://www.w3.org/1999/xhtml}th",
                                                 attrib={"class":"xAxisHdr",
                                                         "style":"text-align:center;max-width:100pt;{0}".format(edgeBorder)})
                             self.rowElts[self.dataFirstRow - 2].insert(thisCol,elt)
                         elif self.type == XML:
                             elt = etree.Element(tableModelQName("label"))
                             self.colHdrElts[self.colHdrRows - 1 + self.colHdrDocRow].insert(thisCol,elt)
                         elt.text = code or "\u00A0"
                     '''
                     xStructuralNodes.append(xStructuralNode)
             if nonAbstract:
                 rightCol += 1
             if renderNow and not childrenFirst:
                 self.xAxis(leftCol + (1 if nonAbstract else 0), topRow + 1, rowBelow, xStructuralNode, xStructuralNodes, childrenFirst, True, False) # render on this pass
             leftCol = rightCol
         return (rightCol, parentRow, widthToSpanParent, noDescendants)