arelle-release 2.37.46__py3-none-any.whl → 2.38.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- arelle/BetaFeatures.py +0 -21
- arelle/Cntlr.py +15 -8
- arelle/CntlrCmdLine.py +121 -56
- arelle/CntlrWinMain.py +143 -70
- arelle/DialogFind.py +1 -1
- arelle/DialogPluginManager.py +6 -4
- arelle/DisclosureSystem.py +7 -0
- arelle/ErrorManager.py +21 -6
- arelle/FileSource.py +11 -4
- arelle/FunctionIxt.py +16 -11
- arelle/HtmlUtil.py +5 -4
- arelle/LeiUtil.py +63 -43
- arelle/ModelDocument.py +20 -15
- arelle/ModelDtsObject.py +8 -0
- arelle/ModelInstanceObject.py +1 -1
- arelle/ModelObject.py +16 -18
- arelle/ModelObjectFactory.py +35 -17
- arelle/ModelXbrl.py +28 -11
- arelle/PluginManager.py +130 -105
- arelle/RuntimeOptions.py +1 -0
- arelle/UrlUtil.py +14 -0
- arelle/Validate.py +17 -12
- arelle/ValidateDuplicateFacts.py +3 -1
- arelle/ValidateFileSource.py +38 -0
- arelle/ValidateFilingText.py +3 -3
- arelle/ValidateXbrl.py +5 -2
- arelle/ValidateXbrlCalcs.py +210 -186
- arelle/ValidateXbrlDTS.py +1 -1
- arelle/ViewFile.py +1 -0
- arelle/ViewFileFactTable.py +2 -2
- arelle/ViewWinDTS.py +4 -1
- arelle/WebCache.py +28 -24
- arelle/XbrlConst.py +22 -0
- arelle/XmlUtil.py +16 -21
- arelle/XmlValidate.py +6 -9
- arelle/_version.py +16 -3
- arelle/api/Session.py +11 -2
- arelle/config/disclosuresystems.xsd +2 -0
- arelle/config/rosettaEntitlements.plist +8 -0
- arelle/conformance/CSVTestcaseLoader.py +1 -1
- arelle/formula/XPathContext.py +3 -3
- arelle/logging/formatters/LogFormatter.py +3 -1
- arelle/packages/report/ReportPackage.py +26 -13
- arelle/packages/report/ReportPackageConst.py +0 -1
- arelle/plugin/inlineXbrlDocumentSet.py +19 -5
- arelle/plugin/validate/DBA/DisclosureSystems.py +19 -1
- arelle/plugin/validate/DBA/PluginValidationDataExtension.py +2 -4
- arelle/plugin/validate/DBA/ValidationPluginExtension.py +2 -1
- arelle/plugin/validate/DBA/resources/config.xml +5 -0
- arelle/plugin/validate/DBA/rules/__init__.py +2 -2
- arelle/plugin/validate/DBA/rules/fr.py +19 -2
- arelle/plugin/validate/DBA/rules/tc.py +2 -0
- arelle/plugin/validate/DBA/rules/th.py +6 -0
- arelle/plugin/validate/DBA/rules/tm.py +18 -5
- arelle/plugin/validate/DBA/rules/tr.py +11 -5
- arelle/plugin/validate/EDINET/Constants.py +193 -9
- arelle/plugin/validate/EDINET/ContextRequirement.py +58 -0
- arelle/plugin/validate/EDINET/ControllerPluginData.py +220 -1
- arelle/plugin/validate/EDINET/CoverItemRequirements.py +42 -0
- arelle/plugin/validate/EDINET/DeiRequirements.py +118 -0
- arelle/plugin/validate/EDINET/FilingFormat.py +275 -0
- arelle/plugin/validate/EDINET/FormType.py +134 -0
- arelle/plugin/validate/EDINET/ManifestInstance.py +72 -5
- arelle/plugin/validate/EDINET/NamespaceConfig.py +50 -0
- arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +493 -132
- arelle/plugin/validate/EDINET/{InstanceType.py → ReportFolderType.py} +72 -15
- arelle/plugin/validate/EDINET/Statement.py +139 -0
- arelle/plugin/validate/EDINET/TableOfContentsBuilder.py +595 -0
- arelle/plugin/validate/EDINET/UploadContents.py +48 -0
- arelle/plugin/validate/EDINET/ValidationPluginExtension.py +20 -2
- arelle/plugin/validate/EDINET/__init__.py +31 -6
- arelle/plugin/validate/EDINET/resources/config.xml +8 -1
- arelle/plugin/validate/EDINET/resources/cover-item-requirements.json +793 -0
- arelle/plugin/validate/EDINET/resources/dei-requirements.csv +27 -0
- arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml +2 -0
- arelle/plugin/validate/EDINET/rules/contexts.py +375 -14
- arelle/plugin/validate/EDINET/rules/edinet.py +1934 -45
- arelle/plugin/validate/EDINET/rules/frta.py +122 -3
- arelle/plugin/validate/EDINET/rules/gfm.py +1907 -11
- arelle/plugin/validate/EDINET/rules/upload.py +989 -141
- arelle/plugin/validate/ESEF/Const.py +3 -1
- arelle/plugin/validate/ESEF/ESEF_2021/DTS.py +5 -0
- arelle/plugin/validate/ESEF/ESEF_2021/Image.py +2 -2
- arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py +23 -20
- arelle/plugin/validate/ESEF/ESEF_Current/DTS.py +47 -14
- arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py +100 -25
- arelle/plugin/validate/ESEF/__init__.py +20 -6
- arelle/plugin/validate/ESEF/resources/authority-validations.json +76 -9
- arelle/plugin/validate/ESEF/resources/config.xml +20 -0
- arelle/plugin/validate/NL/DisclosureSystems.py +22 -0
- arelle/plugin/validate/NL/PluginValidationDataExtension.py +27 -9
- arelle/plugin/validate/NL/ValidationPluginExtension.py +51 -7
- arelle/plugin/validate/NL/resources/config.xml +18 -0
- arelle/plugin/validate/NL/rules/br_kvk.py +17 -61
- arelle/plugin/validate/NL/rules/fg_nl.py +7 -38
- arelle/plugin/validate/NL/rules/fr_kvk.py +7 -42
- arelle/plugin/validate/NL/rules/fr_nl.py +31 -147
- arelle/plugin/validate/NL/rules/nl_kvk.py +142 -28
- arelle/plugin/validate/ROS/PluginValidationDataExtension.py +2 -0
- arelle/plugin/validate/ROS/ValidationPluginExtension.py +4 -1
- arelle/plugin/validate/ROS/rules/ros.py +41 -9
- arelle/plugin/validate/UK/ValidateUK.py +130 -66
- arelle/plugin/validate/UK/__init__.py +89 -103
- arelle/utils/EntryPointDetection.py +79 -13
- arelle/utils/PluginHooks.py +125 -0
- arelle/utils/validate/ESEFImage.py +6 -6
- arelle/utils/validate/Validation.py +18 -0
- arelle/utils/validate/ValidationPlugin.py +76 -11
- arelle/utils/validate/ValidationUtil.py +35 -3
- {arelle_release-2.37.46.dist-info → arelle_release-2.38.0.dist-info}/METADATA +30 -20
- {arelle_release-2.37.46.dist-info → arelle_release-2.38.0.dist-info}/RECORD +115 -191
- {arelle_release-2.37.46.dist-info → arelle_release-2.38.0.dist-info}/licenses/LICENSE.md +0 -3
- arelle/archive/CustomLogger.py +0 -43
- arelle/archive/LoadEFMvalidate.py +0 -32
- arelle/archive/LoadSavePreLbCsv.py +0 -26
- arelle/archive/LoadValidate.cs +0 -31
- arelle/archive/LoadValidate.py +0 -36
- arelle/archive/LoadValidateCmdLine.java +0 -69
- arelle/archive/LoadValidatePostedZip.java +0 -57
- arelle/archive/LoadValidateWebService.java +0 -34
- arelle/archive/SaveTableToExelle.py +0 -140
- arelle/archive/TR3toTR4.py +0 -88
- arelle/archive/plugin/ESEF_2022/__init__.py +0 -47
- arelle/archive/plugin/bigInstance.py +0 -394
- arelle/archive/plugin/cmdWebServerExtension.py +0 -43
- arelle/archive/plugin/crashTest.py +0 -38
- arelle/archive/plugin/functionsXmlCreation.py +0 -106
- arelle/archive/plugin/hello_i18n.pot +0 -26
- arelle/archive/plugin/hello_i18n.py +0 -32
- arelle/archive/plugin/importTestChild1.py +0 -21
- arelle/archive/plugin/importTestChild2.py +0 -22
- arelle/archive/plugin/importTestGrandchild1.py +0 -21
- arelle/archive/plugin/importTestGrandchild2.py +0 -21
- arelle/archive/plugin/importTestImported1.py +0 -23
- arelle/archive/plugin/importTestImported11.py +0 -22
- arelle/archive/plugin/importTestParent.py +0 -48
- arelle/archive/plugin/instanceInfo.py +0 -306
- arelle/archive/plugin/loadFromOIM-2018.py +0 -1282
- arelle/archive/plugin/locale/fr/LC_MESSAGES/hello_i18n.po +0 -25
- arelle/archive/plugin/objectmaker.py +0 -285
- arelle/archive/plugin/packagedImportTest/__init__.py +0 -47
- arelle/archive/plugin/packagedImportTest/importTestChild1.py +0 -21
- arelle/archive/plugin/packagedImportTest/importTestChild2.py +0 -22
- arelle/archive/plugin/packagedImportTest/importTestGrandchild1.py +0 -21
- arelle/archive/plugin/packagedImportTest/importTestGrandchild2.py +0 -21
- arelle/archive/plugin/packagedImportTest/importTestImported1.py +0 -24
- arelle/archive/plugin/packagedImportTest/importTestImported11.py +0 -21
- arelle/archive/plugin/packagedImportTest/subdir/importTestImported111.py +0 -21
- arelle/archive/plugin/packagedImportTest/subdir/subsubdir/importTestImported1111.py +0 -21
- arelle/archive/plugin/sakaCalendar.py +0 -215
- arelle/archive/plugin/saveInstanceInfoset.py +0 -121
- arelle/archive/plugin/sphinx/FormulaGenerator.py +0 -823
- arelle/archive/plugin/sphinx/SphinxContext.py +0 -404
- arelle/archive/plugin/sphinx/SphinxEvaluator.py +0 -783
- arelle/archive/plugin/sphinx/SphinxMethods.py +0 -1287
- arelle/archive/plugin/sphinx/SphinxParser.py +0 -1093
- arelle/archive/plugin/sphinx/SphinxValidator.py +0 -163
- arelle/archive/plugin/sphinx/US-GAAP Ratios Example.xsr +0 -52
- arelle/archive/plugin/sphinx/__init__.py +0 -285
- arelle/archive/plugin/streamingExtensions.py +0 -335
- arelle/archive/plugin/updateTableLB.py +0 -242
- arelle/archive/plugin/validate/SBRnl/CustomLoader.py +0 -19
- arelle/archive/plugin/validate/SBRnl/DTS.py +0 -305
- arelle/archive/plugin/validate/SBRnl/Dimensions.py +0 -357
- arelle/archive/plugin/validate/SBRnl/Document.py +0 -799
- arelle/archive/plugin/validate/SBRnl/Filing.py +0 -467
- arelle/archive/plugin/validate/SBRnl/__init__.py +0 -75
- arelle/archive/plugin/validate/SBRnl/config.xml +0 -26
- arelle/archive/plugin/validate/SBRnl/sbr-nl-taxonomies.xml +0 -754
- arelle/archive/plugin/validate/USBestPractices.py +0 -570
- arelle/archive/plugin/validate/USCorpAction.py +0 -557
- arelle/archive/plugin/validate/USSecTagging.py +0 -337
- arelle/archive/plugin/validate/XDC/__init__.py +0 -77
- arelle/archive/plugin/validate/XDC/config.xml +0 -20
- arelle/archive/plugin/validate/XFsyntax/__init__.py +0 -64
- arelle/archive/plugin/validate/XFsyntax/xf.py +0 -2227
- arelle/archive/plugin/validate/calc2.py +0 -536
- arelle/archive/plugin/validateSchemaLxml.py +0 -156
- arelle/archive/plugin/validateTableInfoset.py +0 -52
- arelle/archive/us-gaap-dei-docType-extraction-frm.xml +0 -90
- arelle/archive/us-gaap-dei-ratio-cash-frm.xml +0 -150
- arelle/examples/plugin/formulaSuiteConverter.py +0 -212
- arelle/examples/plugin/functionsCustom.py +0 -59
- arelle/examples/plugin/hello_dolly.py +0 -64
- arelle/examples/plugin/multi.py +0 -58
- arelle/examples/plugin/rssSaveOim.py +0 -96
- arelle/examples/plugin/validate/XYZ/DisclosureSystems.py +0 -2
- arelle/examples/plugin/validate/XYZ/PluginValidationDataExtension.py +0 -10
- arelle/examples/plugin/validate/XYZ/ValidationPluginExtension.py +0 -49
- arelle/examples/plugin/validate/XYZ/__init__.py +0 -75
- arelle/examples/plugin/validate/XYZ/resources/config.xml +0 -16
- arelle/examples/plugin/validate/XYZ/rules/__init__.py +0 -0
- arelle/examples/plugin/validate/XYZ/rules/rules01.py +0 -110
- arelle/examples/plugin/validate/XYZ/rules/rules02.py +0 -59
- arelle/model/CommentBase.py +0 -9
- arelle/model/ElementBase.py +0 -11
- arelle/model/PIBase.py +0 -10
- arelle/model/__init__.py +0 -15
- arelle/scripts-macOS/startWebServer.command +0 -3
- arelle/scripts-unix/startWebServer.sh +0 -1
- arelle/scripts-windows/startWebServer.bat +0 -5
- {arelle_release-2.37.46.dist-info → arelle_release-2.38.0.dist-info}/WHEEL +0 -0
- {arelle_release-2.37.46.dist-info → arelle_release-2.38.0.dist-info}/entry_points.txt +0 -0
- {arelle_release-2.37.46.dist-info → arelle_release-2.38.0.dist-info}/top_level.txt +0 -0
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
'''
|
|
2
|
-
StreamingExtensions is a plug-in to both GUI menu and command line/web service
|
|
3
|
-
that provides an alternative approach to big instance documents without building a DOM, to save
|
|
4
|
-
memory footprint. lxml iterparse is used to parse the big instance. ModelObjects are specialized by features
|
|
5
|
-
for efficiency and to avoid dependency on an underlying DOM.
|
|
6
|
-
|
|
7
|
-
(Note that this module is based on iterparse, the module under the installation/plugs is much faster.)
|
|
8
|
-
|
|
9
|
-
See COPYRIGHT.md for copyright information.
|
|
10
|
-
'''
|
|
11
|
-
|
|
12
|
-
import io, sys, os, time
|
|
13
|
-
from decimal import Decimal, InvalidOperation
|
|
14
|
-
from lxml import etree
|
|
15
|
-
from collections import defaultdict
|
|
16
|
-
from arelle import XbrlConst, XmlUtil, XmlValidate, ValidateXbrlDimensions
|
|
17
|
-
from arelle.ModelDocument import ModelDocument, Type
|
|
18
|
-
from arelle.ModelObject import ModelObject
|
|
19
|
-
from arelle.ModelObjectFactory import parser
|
|
20
|
-
from arelle.ModelValue import QName
|
|
21
|
-
from arelle.ModelInstanceObject import ModelContext, ModelFact, ModelUnit
|
|
22
|
-
from arelle.Validate import Validate
|
|
23
|
-
from arelle.Version import authorLabel, copyrightLabel
|
|
24
|
-
|
|
25
|
-
_streamingExtensionsValidate = False
|
|
26
|
-
_streamingExtensionsCheck = False
|
|
27
|
-
|
|
28
|
-
def precedingProcessingInstruction(elt, target):
|
|
29
|
-
pi = elt.getprevious()
|
|
30
|
-
while pi is not None:
|
|
31
|
-
if isinstance(pi, etree._ProcessingInstruction) and pi.target == target:
|
|
32
|
-
return pi
|
|
33
|
-
pi = pi.getprevious()
|
|
34
|
-
return None
|
|
35
|
-
|
|
36
|
-
def streamingExtensionsLoader(modelXbrl, mappedUri, filepath):
|
|
37
|
-
# check if big instance and has header with an initial incomplete tree walk (just 2 elements
|
|
38
|
-
def logSyntaxErrors(parsercontext):
|
|
39
|
-
for error in parsercontext.error_log:
|
|
40
|
-
modelXbrl.error("xmlSchema:syntax",
|
|
41
|
-
_("%(error)s, %(fileName)s, line %(line)s, column %(column)s, %(sourceAction)s source element"),
|
|
42
|
-
modelObject=modelDocument, fileName=os.path.basename(filepath),
|
|
43
|
-
error=error.message, line=error.line, column=error.column, sourceAction="streaming")
|
|
44
|
-
#### note: written for iterparse of lxml prior to version 3.3, otherwise rewrite to use XmlPullParser ###
|
|
45
|
-
#### note: iterparse wants a binary file, but file is text mode
|
|
46
|
-
_file, = modelXbrl.fileSource.file(filepath, binary=True)
|
|
47
|
-
startedAt = time.time()
|
|
48
|
-
modelXbrl.profileActivity()
|
|
49
|
-
parsercontext = etree.iterparse(_file, events=("start","end"), huge_tree=True)
|
|
50
|
-
foundInstance = False
|
|
51
|
-
foundErrors = False
|
|
52
|
-
streamingAspects = None
|
|
53
|
-
numRootFacts1 = 0
|
|
54
|
-
numElts = 0
|
|
55
|
-
elt = None
|
|
56
|
-
for event, elt in parsercontext:
|
|
57
|
-
if event == "start":
|
|
58
|
-
if elt.getparent() is not None:
|
|
59
|
-
if elt.getparent().tag == "{http://www.xbrl.org/2003/instance}xbrl":
|
|
60
|
-
if not foundInstance:
|
|
61
|
-
foundInstance = True
|
|
62
|
-
pi = precedingProcessingInstruction(elt, "xbrl-streamable-instance")
|
|
63
|
-
if pi is None:
|
|
64
|
-
break
|
|
65
|
-
else:
|
|
66
|
-
streamingAspects = dict(pi.attrib.copy())
|
|
67
|
-
if not elt.tag.startswith("{http://www.xbrl.org/"):
|
|
68
|
-
numRootFacts1 += 1
|
|
69
|
-
if numRootFacts1 % 1000 == 0:
|
|
70
|
-
modelXbrl.profileActivity("... streaming tree check", minTimeToShow=20.0)
|
|
71
|
-
elif not foundInstance:
|
|
72
|
-
break
|
|
73
|
-
elif elt.tag == "{http://www.xbrl.org/2003/instance}xbrl" and precedingProcessingInstruction(elt, "xbrl-streamable-instance") is not None:
|
|
74
|
-
modelXbrl.error("streamingExtensions:headerMisplaced",
|
|
75
|
-
_("Header is misplaced: %(error)s, must follow xbrli:xbrl element"),
|
|
76
|
-
modelObject=elt)
|
|
77
|
-
elif event == "end":
|
|
78
|
-
elt.clear()
|
|
79
|
-
numElts += 1
|
|
80
|
-
if numElts % 1000 == 0 and elt.getparent() is not None:
|
|
81
|
-
while elt.getprevious() is not None and elt.getparent() is not None:
|
|
82
|
-
del elt.getparent()[0]
|
|
83
|
-
if elt is not None:
|
|
84
|
-
elt.clear()
|
|
85
|
-
_file.seek(0,io.SEEK_SET) # allow reparsing
|
|
86
|
-
if not foundInstance or streamingAspects is None:
|
|
87
|
-
del elt, parsercontext
|
|
88
|
-
_file.close()
|
|
89
|
-
return None
|
|
90
|
-
modelXbrl.profileStat(_("streaming tree check"), time.time() - startedAt)
|
|
91
|
-
startedAt = time.time()
|
|
92
|
-
try:
|
|
93
|
-
version = Decimal(streamingAspects.get("version"))
|
|
94
|
-
if int(version) != 1:
|
|
95
|
-
modelXbrl.error("streamingExtensions:unsupportedVersion",
|
|
96
|
-
_("Streaming version %(version)s, major version number must be 1"),
|
|
97
|
-
modelObject=elt, version=version)
|
|
98
|
-
foundErrors = True
|
|
99
|
-
except (InvalidOperation, OverflowError):
|
|
100
|
-
modelXbrl.error("streamingExtensions:versionError",
|
|
101
|
-
_("Version %(version)s, number must be 1.n"),
|
|
102
|
-
modelObject=elt, version=streamingAspects.get("version", "(none)"))
|
|
103
|
-
foundErrors = True
|
|
104
|
-
for bufAspect in ("contextBuffer", "unitBuffer", "footnoteBuffer"):
|
|
105
|
-
try:
|
|
106
|
-
bufLimit = Decimal(streamingAspects.get(bufAspect, "INF"))
|
|
107
|
-
if bufLimit < 1 or (bufLimit.is_finite() and bufLimit % 1 != 0):
|
|
108
|
-
raise InvalidOperation
|
|
109
|
-
elif bufAspect == "contextBuffer":
|
|
110
|
-
contextBufferLimit = bufLimit
|
|
111
|
-
elif bufAspect == "unitBuffer":
|
|
112
|
-
unitBufferLimit = bufLimit
|
|
113
|
-
elif bufAspect == "footnoteBuffer":
|
|
114
|
-
footnoteBufferLimit = bufLimit
|
|
115
|
-
except InvalidOperation:
|
|
116
|
-
modelXbrl.error("streamingExtensions:valueError",
|
|
117
|
-
_("Streaming %(attrib)s %(value)s, number must be a positive integer or INF"),
|
|
118
|
-
modelObject=elt, attrib=bufAspect, value=streamingAspects.get(bufAspect))
|
|
119
|
-
foundErrors = True
|
|
120
|
-
if parsercontext.error_log:
|
|
121
|
-
foundErrors = True
|
|
122
|
-
logSyntaxErrors(parsercontext)
|
|
123
|
-
|
|
124
|
-
if foundErrors:
|
|
125
|
-
_file.close()
|
|
126
|
-
return None
|
|
127
|
-
parsercontext = etree.iterparse(_file, events=("start","end"), huge_tree=True)
|
|
128
|
-
_parser, _parserLookupName, _parserLookupClass = parser(modelXbrl,filepath)
|
|
129
|
-
eltMdlObjs = {}
|
|
130
|
-
beforeInstanceStream = True
|
|
131
|
-
validator = None
|
|
132
|
-
contextBuffer = []
|
|
133
|
-
unitBuffer = []
|
|
134
|
-
footnoteBuffer = []
|
|
135
|
-
factBuffer = []
|
|
136
|
-
numFacts = numRootFacts2 = 1
|
|
137
|
-
for event, elt in parsercontext:
|
|
138
|
-
if event == "start":
|
|
139
|
-
mdlObj = _parser.makeelement(elt.tag, attrib=elt.attrib, nsmap=elt.nsmap)
|
|
140
|
-
mdlObj.sourceline = elt.sourceline
|
|
141
|
-
eltMdlObjs[elt] = mdlObj
|
|
142
|
-
if elt.getparent() is None:
|
|
143
|
-
modelDocument = ModelDocument(modelXbrl, Type.INSTANCE, mappedUri, filepath, etree.ElementTree(mdlObj))
|
|
144
|
-
modelDocument.xmlRootElement = mdlObj
|
|
145
|
-
modelXbrl.modelDocument = modelDocument # needed for incremental validation
|
|
146
|
-
mdlObj.init(modelDocument)
|
|
147
|
-
modelXbrl.info("streamingExtensions:streaming",
|
|
148
|
-
_("Stream processing this instance."),
|
|
149
|
-
modelObject = modelDocument)
|
|
150
|
-
else:
|
|
151
|
-
eltMdlObjs[elt.getparent()].append(mdlObj)
|
|
152
|
-
mdlObj._init()
|
|
153
|
-
ns = mdlObj.namespaceURI
|
|
154
|
-
ln = mdlObj.localName
|
|
155
|
-
if (beforeInstanceStream and (
|
|
156
|
-
(ns == XbrlConst.link and ln not in ("schemaRef", "linkbaseRef")) or
|
|
157
|
-
(ns == XbrlConst.xbrli and ln in ("context", "unit")) or
|
|
158
|
-
(ns not in (XbrlConst.link, XbrlConst.xbrli)))):
|
|
159
|
-
beforeInstanceStream = False
|
|
160
|
-
if _streamingExtensionsValidate:
|
|
161
|
-
validator = Validate(modelXbrl)
|
|
162
|
-
validator.instValidator.validate(modelXbrl, modelXbrl.modelManager.formulaOptions.typedParameters(modelXbrl.prefixedNamespaces))
|
|
163
|
-
else: # need default dimensions
|
|
164
|
-
ValidateXbrlDimensions.loadDimensionDefaults(modelXbrl)
|
|
165
|
-
mdlObj = None # deref
|
|
166
|
-
|
|
167
|
-
elif event == "end":
|
|
168
|
-
mdlObj = eltMdlObjs.pop(elt)
|
|
169
|
-
if elt.text: # text available after child nodes processed
|
|
170
|
-
mdlObj.text = elt.text
|
|
171
|
-
ns = mdlObj.namespaceURI
|
|
172
|
-
ln = mdlObj.localName
|
|
173
|
-
parentMdlObj = mdlObj.getparent()
|
|
174
|
-
if ns == XbrlConst.xbrli:
|
|
175
|
-
if ln == "context":
|
|
176
|
-
if mdlObj.get("sticky"):
|
|
177
|
-
del mdlObj.attrib["sticky"]
|
|
178
|
-
modelDocument.contextDiscover(mdlObj)
|
|
179
|
-
else:
|
|
180
|
-
if _streamingExtensionsValidate and len(contextBuffer) >= contextBufferLimit:
|
|
181
|
-
# drop before adding as dropped may have same id as added
|
|
182
|
-
cntx = contextBuffer.pop(0)
|
|
183
|
-
dropContext(modelXbrl, cntx)
|
|
184
|
-
del parentMdlObj[parentMdlObj.index(cntx)]
|
|
185
|
-
cntx = None
|
|
186
|
-
modelDocument.contextDiscover(mdlObj)
|
|
187
|
-
if contextBufferLimit.is_finite():
|
|
188
|
-
contextBuffer.append(mdlObj)
|
|
189
|
-
if _streamingExtensionsValidate:
|
|
190
|
-
contextsToCheck = (mdlObj,)
|
|
191
|
-
validator.instValidator.checkContexts(contextsToCheck)
|
|
192
|
-
if modelXbrl.hasXDT:
|
|
193
|
-
validator.instValidator.checkContextsDimensions(contextsToCheck)
|
|
194
|
-
del contextsToCheck # dereference
|
|
195
|
-
elif ln == "unit":
|
|
196
|
-
if _streamingExtensionsValidate and len(unitBuffer) >= unitBufferLimit:
|
|
197
|
-
# drop before additing as dropped may have same id as added
|
|
198
|
-
unit = unitBuffer.pop(0)
|
|
199
|
-
dropUnit(modelXbrl, unit)
|
|
200
|
-
del parentMdlObj[parentMdlObj.index(unit)]
|
|
201
|
-
unit = None
|
|
202
|
-
modelDocument.unitDiscover(mdlObj)
|
|
203
|
-
if unitBufferLimit.is_finite():
|
|
204
|
-
unitBuffer.append(mdlObj)
|
|
205
|
-
if _streamingExtensionsValidate:
|
|
206
|
-
validator.instValidator.checkUnits( (mdlObj,) )
|
|
207
|
-
elif ln == "xbrl": # end of document
|
|
208
|
-
# check remaining footnote refs
|
|
209
|
-
for footnoteLink in footnoteBuffer:
|
|
210
|
-
checkFootnoteHrefs(modelXbrl, footnoteLink)
|
|
211
|
-
elt.clear()
|
|
212
|
-
elif ns == XbrlConst.link:
|
|
213
|
-
if ln in ("schemaRef", "linkbaseRef"):
|
|
214
|
-
modelDocument.discoverHref(mdlObj)
|
|
215
|
-
elif ln in ("roleRef", "arcroleRef"):
|
|
216
|
-
modelDocument.linkbaseDiscover((mdlObj,), inInstance=True)
|
|
217
|
-
elif ln == "footnoteLink":
|
|
218
|
-
footnoteLinks = (mdlObj,)
|
|
219
|
-
modelDocument.linkbaseDiscover(footnoteLinks, inInstance=True)
|
|
220
|
-
if footnoteBufferLimit.is_finite():
|
|
221
|
-
footnoteBuffer.append(mdlObj)
|
|
222
|
-
if _streamingExtensionsValidate:
|
|
223
|
-
validator.instValidator.checkLinks(footnoteLinks)
|
|
224
|
-
if len(footnoteBuffer) > footnoteBufferLimit:
|
|
225
|
-
# check that hrefObjects for locators were all satisfied
|
|
226
|
-
# drop before addition as dropped may have same id as added
|
|
227
|
-
footnoteLink = footnoteBuffer.pop(0)
|
|
228
|
-
checkFootnoteHrefs(modelXbrl, footnoteLink)
|
|
229
|
-
dropFootnoteLink(modelXbrl, footnoteLink)
|
|
230
|
-
del parentMdlObj[parentMdlObj.index(footnoteLink)]
|
|
231
|
-
footnoteLink = None
|
|
232
|
-
footnoteLinks = None
|
|
233
|
-
elt.clear()
|
|
234
|
-
elif parentMdlObj.qname == XbrlConst.qnXbrliXbrl:
|
|
235
|
-
numRootFacts2 += 1
|
|
236
|
-
modelDocument.factDiscover(mdlObj, modelXbrl.facts)
|
|
237
|
-
XmlValidate.validate(modelXbrl, mdlObj)
|
|
238
|
-
if _streamingExtensionsValidate:
|
|
239
|
-
factsToCheck = (mdlObj,)
|
|
240
|
-
validator.instValidator.checkFacts(factsToCheck)
|
|
241
|
-
if modelXbrl.hasXDT:
|
|
242
|
-
validator.instValidator.checkFactsDimensions(factsToCheck)
|
|
243
|
-
del factsToCheck
|
|
244
|
-
dropFact(modelXbrl, mdlObj, modelXbrl.facts)
|
|
245
|
-
del parentMdlObj[parentMdlObj.index(mdlObj)]
|
|
246
|
-
if numRootFacts2 % 1000 == 0:
|
|
247
|
-
modelXbrl.profileActivity("... streaming fact {0} of {1} {2:.2f}%".format(numRootFacts2, numRootFacts1, 100.0 * numRootFacts2 / numRootFacts1),
|
|
248
|
-
minTimeToShow=20.0)
|
|
249
|
-
# get rid of root element from iterparse's tree
|
|
250
|
-
elt.clear()
|
|
251
|
-
while elt.getprevious() is not None: # cleans up any prior siblings
|
|
252
|
-
del elt.getparent()[0]
|
|
253
|
-
mdlObj = None # deref
|
|
254
|
-
logSyntaxErrors(parsercontext)
|
|
255
|
-
del parsercontext
|
|
256
|
-
if validator is not None:
|
|
257
|
-
validator.close()
|
|
258
|
-
_file.close()
|
|
259
|
-
modelXbrl.profileStat(_("streaming complete"), time.time() - startedAt)
|
|
260
|
-
return modelDocument
|
|
261
|
-
|
|
262
|
-
def checkFootnoteHrefs(modelXbrl, footnoteLink):
|
|
263
|
-
for locElt in footnoteLink.iterchildren(tag="{http://www.xbrl.org/2003/linkbase}loc"):
|
|
264
|
-
for hrefElt, doc, id in footnoteLink.modelDocument.hrefObjects:
|
|
265
|
-
if locElt == hrefElt and id not in footnoteLink.modelDocument.idObjects:
|
|
266
|
-
modelXbrl.error("streamingExtensions:footnoteId",
|
|
267
|
-
_("Footnote id %(id)s not matched to fact in buffered region"),
|
|
268
|
-
modelObject=footnoteLink, id=id)
|
|
269
|
-
|
|
270
|
-
def dropContext(modelXbrl, cntx):
|
|
271
|
-
del modelXbrl.contexts[cntx.id]
|
|
272
|
-
dropObject(modelXbrl, cntx)
|
|
273
|
-
|
|
274
|
-
def dropUnit(modelXbrl, unit):
|
|
275
|
-
del modelXbrl.units[unit.id]
|
|
276
|
-
dropObject(modelXbrl, unit)
|
|
277
|
-
|
|
278
|
-
def dropFootnoteLink(modelXbrl, footnoteLink):
|
|
279
|
-
for baseSet in modelXbrl.baseSets.values():
|
|
280
|
-
if footnoteLink in baseSet:
|
|
281
|
-
baseSet.remove(footnoteLink)
|
|
282
|
-
dropObject(modelXbrl, footnoteLink)
|
|
283
|
-
|
|
284
|
-
def dropFact(modelXbrl, fact, facts):
|
|
285
|
-
while fact.modelTupleFacts:
|
|
286
|
-
dropFact(modelXbrl, fact.modelTupleFacts[0], fact.modelTupleFacts)
|
|
287
|
-
modelXbrl.factsInInstance.discard(fact)
|
|
288
|
-
facts.remove(fact)
|
|
289
|
-
modelXbrl.modelObjects[fact.objectIndex] = None # objects found by index, can't remove position from list
|
|
290
|
-
fact.modelDocument.modelObjects.remove(fact)
|
|
291
|
-
fact.clear()
|
|
292
|
-
|
|
293
|
-
def dropObject(modelXbrl, mdlObj):
|
|
294
|
-
for childObj in mdlObj.iterchildren():
|
|
295
|
-
dropObject(modelXbrl, childObj)
|
|
296
|
-
if mdlObj.qname == XbrlConst.qnLinkLoc:
|
|
297
|
-
hrefs = mdlObj.modelDocument.hrefObjects
|
|
298
|
-
removedHrefs = [i for i, hrefObj in enumerate(hrefs) if mdlObj == hrefObj[0]]
|
|
299
|
-
for i in removedHrefs:
|
|
300
|
-
del hrefs[i]
|
|
301
|
-
modelXbrl.modelObjects[mdlObj.objectIndex] = None # objects found by index, can't remove position from list
|
|
302
|
-
mdlObj.modelDocument.modelObjects.remove(mdlObj)
|
|
303
|
-
mdlObj.modelDocument.idObjects.pop(mdlObj.id, None)
|
|
304
|
-
mdlObj.clear()
|
|
305
|
-
|
|
306
|
-
def streamingOptionsExtender(parser):
|
|
307
|
-
parser.add_option("--check-streaming",
|
|
308
|
-
action="store_true",
|
|
309
|
-
dest="check_streaming",
|
|
310
|
-
help=_('Check streamability of instance document."'))
|
|
311
|
-
|
|
312
|
-
def streamingExtensionsSetup(self, options, **kwargs):
|
|
313
|
-
global _streamingExtensionsCheck, _streamingExtensionsValidate
|
|
314
|
-
_streamingExtensionsCheck = getattr(options, 'check_streaming', False)
|
|
315
|
-
_streamingExtensionsValidate = options.validate
|
|
316
|
-
if options.validate:
|
|
317
|
-
options.validate = False # prevent cmdLine calling validation
|
|
318
|
-
|
|
319
|
-
'''
|
|
320
|
-
Do not use _( ) in pluginInfo itself (it is applied later, after loading
|
|
321
|
-
'''
|
|
322
|
-
|
|
323
|
-
__pluginInfo__ = {
|
|
324
|
-
'name': 'Streaming Extensions Loader',
|
|
325
|
-
'version': '0.9',
|
|
326
|
-
'description': "This plug-in loads big XBRL instances without building a DOM in memory. "
|
|
327
|
-
"lxml iterparse parses XBRL directly into an object model without a DOM. ",
|
|
328
|
-
'license': 'Apache-2',
|
|
329
|
-
'author': authorLabel,
|
|
330
|
-
'copyright': copyrightLabel,
|
|
331
|
-
# classes of mount points (required)
|
|
332
|
-
'CntlrCmdLine.Options': streamingOptionsExtender,
|
|
333
|
-
'CntlrCmdLine.Utility.Run': streamingExtensionsSetup,
|
|
334
|
-
'ModelDocument.PullLoader': streamingExtensionsLoader,
|
|
335
|
-
}
|
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
'''
|
|
2
|
-
Update Table Linkbase is an example of a plug-in to both GUI menu and command line/web service
|
|
3
|
-
that updates a table linkbase from Eurofiling 2010 syntax to XII 2011 PWD syntax and saves it.
|
|
4
|
-
|
|
5
|
-
See COPYRIGHT.md for copyright information.
|
|
6
|
-
'''
|
|
7
|
-
from arelle.Version import authorLabel, copyrightLabel
|
|
8
|
-
|
|
9
|
-
def generateUpdatedTableLB(dts, updatedTableLinkbaseFile):
|
|
10
|
-
import os, io
|
|
11
|
-
from arelle import XmlUtil, XbrlConst
|
|
12
|
-
from arelle.ViewUtil import viewReferences, referenceURI
|
|
13
|
-
from arelle.ModelRenderingObject import ModelEuAxisCoord
|
|
14
|
-
|
|
15
|
-
if dts.fileSource.isArchive:
|
|
16
|
-
dts.error("genTblLB:outFileIsArchive",
|
|
17
|
-
_("Updated Table Linkbase file cannot be an archive: %(tableLBOutputFile)s."),
|
|
18
|
-
modelObject=dts, tableLBOutputFile=updatedTableLinkbaseFile)
|
|
19
|
-
return
|
|
20
|
-
tblAxisRelSet = dts.relationshipSet(XbrlConst.euTableAxis)
|
|
21
|
-
axisMbrRelSet = dts.relationshipSet(XbrlConst.euAxisMember)
|
|
22
|
-
if len(tblAxisRelSet.modelRelationships) == 0:
|
|
23
|
-
dts.error("genTblLB:noInputTables",
|
|
24
|
-
_("DTS does not contain Eurofiling 2010 tables and axes: %(entryFile)s."),
|
|
25
|
-
modelObject=dts, entryFile=dts.uri)
|
|
26
|
-
return
|
|
27
|
-
|
|
28
|
-
file = io.StringIO('''
|
|
29
|
-
<nsmap>
|
|
30
|
-
<link:linkbase
|
|
31
|
-
xmlns:label="http://xbrl.org/2008/label"
|
|
32
|
-
xmlns:gen="http://xbrl.org/2008/generic"
|
|
33
|
-
xmlns:df="http://xbrl.org/2008/filter/dimension"
|
|
34
|
-
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
35
|
-
xmlns:reference="http://xbrl.org/2008/reference"
|
|
36
|
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
37
|
-
xmlns:link="http://www.xbrl.org/2003/linkbase"
|
|
38
|
-
xmlns:table="http://xbrl.org/2011/table"
|
|
39
|
-
xmlns:formula="http://xbrl.org/2008/formula"
|
|
40
|
-
xsi:schemaLocation="
|
|
41
|
-
http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd
|
|
42
|
-
http://xbrl.org/2008/generic http://www.xbrl.org/2008/generic-link.xsd
|
|
43
|
-
http://xbrl.org/2008/reference http://www.xbrl.org/2008/generic-reference.xsd
|
|
44
|
-
http://xbrl.org/2008/label http://www.xbrl.org/2008/generic-label.xsd
|
|
45
|
-
http://xbrl.org/2011/table http://www.xbrl.org/2011/table.xsd
|
|
46
|
-
http://xbrl.org/2008/filter/dimension http://www.xbrl.org/2008/dimension-filter.xsd">
|
|
47
|
-
<link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/table-filter" xlink:type="simple"
|
|
48
|
-
xlink:href="http://www.xbrl.org/2011/table.xsd#table-filter"/>
|
|
49
|
-
<link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/table-axis" xlink:type="simple"
|
|
50
|
-
xlink:href="http://www.xbrl.org/2011/table.xsd#table-axis"/>
|
|
51
|
-
<link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/axis-subtree" xlink:type="simple"
|
|
52
|
-
xlink:href="http://www.xbrl.org/2011/table.xsd#axis-subtree"/>
|
|
53
|
-
<link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/axis-filter" xlink:type="simple"
|
|
54
|
-
xlink:href="http://www.xbrl.org/2011/filter-axis.xsd#axis-filter"/>
|
|
55
|
-
</link:linkbase>
|
|
56
|
-
</nsmap>
|
|
57
|
-
<!-- Generated by Arelle(r) http://arelle.org -->
|
|
58
|
-
'''
|
|
59
|
-
)
|
|
60
|
-
from arelle.ModelObjectFactory import parser
|
|
61
|
-
parser, parserLookupName, parserLookupClass = parser(dts,None)
|
|
62
|
-
from lxml import etree
|
|
63
|
-
xmlDocument = etree.parse(file,parser=parser,base_url=updatedTableLinkbaseFile)
|
|
64
|
-
file.close()
|
|
65
|
-
nsmapElt = xmlDocument.getroot()
|
|
66
|
-
#xmlDocument.getroot().init(self) ## is this needed ??
|
|
67
|
-
for lbElement in xmlDocument.iter(tag="{http://www.xbrl.org/2003/linkbase}linkbase"):
|
|
68
|
-
break
|
|
69
|
-
|
|
70
|
-
class DocObj: # fake ModelDocument for namespaces
|
|
71
|
-
def __init__(self):
|
|
72
|
-
self.xmlRootElement = lbElement
|
|
73
|
-
self.xmlDocument = xmlDocument
|
|
74
|
-
docObj = DocObj()
|
|
75
|
-
|
|
76
|
-
numELRs = 0
|
|
77
|
-
numTables = 0
|
|
78
|
-
|
|
79
|
-
def copyAttrs(fromElt, toElt, attrTags):
|
|
80
|
-
for attr in attrTags:
|
|
81
|
-
if fromElt.get(attr):
|
|
82
|
-
toElt.set(attr, fromElt.get(attr))
|
|
83
|
-
|
|
84
|
-
def generateTable(newLinkElt, newTblElt, srcTblElt, tblAxisRelSet, axisMbrRelSet, visited):
|
|
85
|
-
if srcTblElt is not None:
|
|
86
|
-
for rel in tblAxisRelSet.fromModelObject(srcTblElt):
|
|
87
|
-
srcAxisElt = rel.toModelObject
|
|
88
|
-
if isinstance(srcAxisElt, ModelEuAxisCoord):
|
|
89
|
-
visited.add(srcAxisElt)
|
|
90
|
-
newAxisElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}ruleAxis")
|
|
91
|
-
copyAttrs(srcAxisElt, newAxisElt, ("id",
|
|
92
|
-
"{http://www.w3.org/1999/xlink}type",
|
|
93
|
-
"{http://www.w3.org/1999/xlink}label"))
|
|
94
|
-
newAxisElt.set("abstract", "true") # always true on root element
|
|
95
|
-
newArcElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}axisArc")
|
|
96
|
-
copyAttrs(rel, newArcElt, ("id",
|
|
97
|
-
"{http://www.w3.org/1999/xlink}type",
|
|
98
|
-
"{http://www.w3.org/1999/xlink}from",
|
|
99
|
-
"{http://www.w3.org/1999/xlink}to",
|
|
100
|
-
"order"))
|
|
101
|
-
newArcElt.set("{http://www.w3.org/1999/xlink}arcrole", XbrlConst.tableBreakdown)
|
|
102
|
-
newArcElt.set("axisDisposition", rel.axisDisposition)
|
|
103
|
-
generateAxis(newLinkElt, newAxisElt, srcAxisElt, axisMbrRelSet, visited)
|
|
104
|
-
visited.discard(srcAxisElt)
|
|
105
|
-
|
|
106
|
-
def generateAxis(newLinkElt, newAxisParentElt, srcAxisElt, axisMbrRelSet, visited):
|
|
107
|
-
for rel in axisMbrRelSet.fromModelObject(srcAxisElt):
|
|
108
|
-
tgtAxisElt = rel.toModelObject
|
|
109
|
-
if isinstance(tgtAxisElt, ModelEuAxisCoord) and tgtAxisElt not in visited:
|
|
110
|
-
visited.add(tgtAxisElt)
|
|
111
|
-
newAxisElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}ruleAxis")
|
|
112
|
-
copyAttrs(tgtAxisElt, newAxisElt, ("id",
|
|
113
|
-
"abstract",
|
|
114
|
-
"{http://www.w3.org/1999/xlink}type",
|
|
115
|
-
"{http://www.w3.org/1999/xlink}label"))
|
|
116
|
-
if tgtAxisElt.primaryItemQname:
|
|
117
|
-
newRuleElt = etree.SubElement(newAxisElt, "{http://xbrl.org/2008/formula}concept")
|
|
118
|
-
newQnameElt = etree.SubElement(newRuleElt, "{http://xbrl.org/2008/formula}qname")
|
|
119
|
-
newQnameElt.text = XmlUtil.addQnameValue(docObj, tgtAxisElt.primaryItemQname)
|
|
120
|
-
for dimQname, memQname in tgtAxisElt.explicitDims:
|
|
121
|
-
newRuleElt = etree.SubElement(newAxisElt, "{http://xbrl.org/2008/formula}explicitDimension")
|
|
122
|
-
newRuleElt.set("dimension", XmlUtil.addQnameValue(docObj, dimQname))
|
|
123
|
-
newMbrElt = etree.SubElement(newRuleElt, "{http://xbrl.org/2008/formula}member")
|
|
124
|
-
newQnameElt = etree.SubElement(newMbrElt, "{http://xbrl.org/2008/formula}qname")
|
|
125
|
-
newQnameElt.text = XmlUtil.addQnameValue(docObj, memQname)
|
|
126
|
-
newArcElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}axisArc")
|
|
127
|
-
copyAttrs(rel, newArcElt, ("id",
|
|
128
|
-
"{http://www.w3.org/1999/xlink}type",
|
|
129
|
-
"{http://www.w3.org/1999/xlink}from",
|
|
130
|
-
"{http://www.w3.org/1999/xlink}to",
|
|
131
|
-
"order"))
|
|
132
|
-
newArcElt.set("{http://www.w3.org/1999/xlink}arcrole", XbrlConst.tableAxisSubtree)
|
|
133
|
-
generateAxis(newLinkElt, newAxisElt, tgtAxisElt, axisMbrRelSet, visited)
|
|
134
|
-
visited.discard(tgtAxisElt)
|
|
135
|
-
|
|
136
|
-
# sort URIs
|
|
137
|
-
linkroleUris = sorted([linkroleUri
|
|
138
|
-
for linkroleUri in tblAxisRelSet.linkRoleUris])
|
|
139
|
-
|
|
140
|
-
firstNewLinkElt = None
|
|
141
|
-
roleRefUris = set()
|
|
142
|
-
for linkroleUri in linkroleUris:
|
|
143
|
-
numELRs += 1
|
|
144
|
-
newLinkElt = etree.SubElement(lbElement, "{http://xbrl.org/2008/generic}link")
|
|
145
|
-
newLinkElt.set("{http://www.w3.org/1999/xlink}type", "extended")
|
|
146
|
-
newLinkElt.set("{http://www.w3.org/1999/xlink}role", linkroleUri)
|
|
147
|
-
if firstNewLinkElt is None: firstNewLinkElt = newLinkElt
|
|
148
|
-
# To do: add roleRef if needed
|
|
149
|
-
tblAxisRelSet = dts.relationshipSet(XbrlConst.euTableAxis, linkroleUri)
|
|
150
|
-
axisMbrRelSet = dts.relationshipSet(XbrlConst.euAxisMember, linkroleUri)
|
|
151
|
-
for srcTblElt in tblAxisRelSet.rootConcepts:
|
|
152
|
-
if srcTblElt.tag == "{http://www.eurofiling.info/2010/rendering}table":
|
|
153
|
-
numTables += 1
|
|
154
|
-
newTblElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}table")
|
|
155
|
-
newTblElt.set("aspectModel", "dimensional")
|
|
156
|
-
copyAttrs(srcTblElt, newTblElt, ("id",
|
|
157
|
-
"{http://www.w3.org/1999/xlink}type",
|
|
158
|
-
"{http://www.w3.org/1999/xlink}label"))
|
|
159
|
-
generateTable(newLinkElt, newTblElt, srcTblElt, tblAxisRelSet, axisMbrRelSet, set())
|
|
160
|
-
|
|
161
|
-
if linkroleUri not in roleRefUris:
|
|
162
|
-
srcRoleRefElt = XmlUtil.descendant(srcTblElt.getroottree(), XbrlConst.link, "roleRef", "roleURI", linkroleUri)
|
|
163
|
-
if srcRoleRefElt is not None:
|
|
164
|
-
roleRefUris.add(linkroleUri)
|
|
165
|
-
newRoleRefElt = etree.Element("{http://www.xbrl.org/2003/linkbase}roleRef")
|
|
166
|
-
copyAttrs(srcRoleRefElt, newRoleRefElt, ("roleURI",
|
|
167
|
-
"{http://www.w3.org/1999/xlink}type",
|
|
168
|
-
"{http://www.w3.org/1999/xlink}href"))
|
|
169
|
-
firstNewLinkElt.addprevious(newRoleRefElt)
|
|
170
|
-
|
|
171
|
-
fh = open(updatedTableLinkbaseFile, "w", encoding="utf-8")
|
|
172
|
-
XmlUtil.writexml(fh, xmlDocument, encoding="utf-8")
|
|
173
|
-
fh.close()
|
|
174
|
-
|
|
175
|
-
dts.info("info:updateTableLinkbase",
|
|
176
|
-
_("Updated Table Linkbase of %(entryFile)s has %(numberOfLinkroles)s linkroles, %(numberOfTables)s tables in file %(tableLBOutputFile)s."),
|
|
177
|
-
modelObject=dts,
|
|
178
|
-
entryFile=dts.uri, numberOfLinkroles=numELRs, numberOfTables=numTables, tableLBOutputFile=updatedTableLinkbaseFile)
|
|
179
|
-
|
|
180
|
-
def updateTableLBMenuEntender(cntlr, menu):
|
|
181
|
-
# Extend menu with an item for the savedts plugin
|
|
182
|
-
menu.add_command(label="Update table linkbase",
|
|
183
|
-
underline=0,
|
|
184
|
-
command=lambda: updateTableLBMenuCommand(cntlr) )
|
|
185
|
-
|
|
186
|
-
def updateTableLBMenuCommand(cntlr):
|
|
187
|
-
# save DTS menu item has been invoked
|
|
188
|
-
if cntlr.modelManager is None or cntlr.modelManager.modelXbrl is None:
|
|
189
|
-
cntlr.addToLog("No taxonomy loaded.")
|
|
190
|
-
return
|
|
191
|
-
|
|
192
|
-
# get file name into which to save log file while in foreground thread
|
|
193
|
-
updatedTableLinkbaseFile = cntlr.uiFileDialog("save",
|
|
194
|
-
title=_("arelle - Save Updated Table Linkbase file"),
|
|
195
|
-
initialdir=cntlr.config.setdefault("tableLinkbaseFileDir","."),
|
|
196
|
-
filetypes=[(_("Linkbase file .xml"), "*.xml")],
|
|
197
|
-
defaultextension=".xml")
|
|
198
|
-
if not updatedTableLinkbaseFile:
|
|
199
|
-
return False
|
|
200
|
-
import os
|
|
201
|
-
cntlr.config["tableLinkbaseFileDir"] = os.path.dirname(updatedTableLinkbaseFile)
|
|
202
|
-
cntlr.saveConfig()
|
|
203
|
-
|
|
204
|
-
try:
|
|
205
|
-
generateUpdatedTableLB(cntlr.modelManager.modelXbrl, updatedTableLinkbaseFile)
|
|
206
|
-
except Exception as ex:
|
|
207
|
-
dts = cntlr.modelManager.modelXbrl
|
|
208
|
-
dts.error("exception",
|
|
209
|
-
_("Updated table linkbase generation exception: %(error)s"), error=ex,
|
|
210
|
-
modelXbrl=dts,
|
|
211
|
-
exc_info=True)
|
|
212
|
-
|
|
213
|
-
def updateTableLBCommandLineOptionExtender(parser):
|
|
214
|
-
# extend command line options with a save DTS option
|
|
215
|
-
parser.add_option("--save-updated-table-linkbase",
|
|
216
|
-
action="store",
|
|
217
|
-
dest="updatedTableLinkbaseFile",
|
|
218
|
-
help=_("Update table linkbase file from Eurofiling 2010 to XII 2011 syntax."))
|
|
219
|
-
|
|
220
|
-
def updateTableLBCommandLineXbrlRun(cntlr, options, modelXbrl, *args, **kwargs):
|
|
221
|
-
# extend XBRL-loaded run processing for this option
|
|
222
|
-
if getattr(options, "updatedTableLinkbaseFile", None):
|
|
223
|
-
if cntlr.modelManager is None or cntlr.modelManager.modelXbrl is None:
|
|
224
|
-
cntlr.addToLog("No taxonomy loaded.")
|
|
225
|
-
return
|
|
226
|
-
generateUpdatedTableLB(cntlr.modelManager.modelXbrl, options.updatedTableLinkbaseFile)
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
__pluginInfo__ = {
|
|
230
|
-
'name': 'Update Table Linkbase',
|
|
231
|
-
'version': '0.9',
|
|
232
|
-
'description': "This plug-in updates a table linkbase from Eurofiling 2010 syntax to XII 2011 PWD syntax. "
|
|
233
|
-
"The updated linkbase is saved to a local file. "
|
|
234
|
-
"Hrefs in the new file are identical the prior hrefs (not offset considering save-to directory). ",
|
|
235
|
-
'license': 'Apache-2',
|
|
236
|
-
'author': authorLabel,
|
|
237
|
-
'copyright': copyrightLabel,
|
|
238
|
-
# classes of mount points (required)
|
|
239
|
-
'CntlrWinMain.Menu.Tools': updateTableLBMenuEntender,
|
|
240
|
-
'CntlrCmdLine.Options': updateTableLBCommandLineOptionExtender,
|
|
241
|
-
'CntlrCmdLine.Xbrl.Run': updateTableLBCommandLineXbrlRun,
|
|
242
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
'''
|
|
2
|
-
See COPYRIGHT.md for copyright information.
|
|
3
|
-
'''
|
|
4
|
-
import regex as re
|
|
5
|
-
|
|
6
|
-
def checkForBOMs(modelXbrl, file, mappedUri, filepath, *args, **kwargs):
|
|
7
|
-
# callback is for all opened docs, must only process when SBRNL validation active
|
|
8
|
-
if (modelXbrl.modelManager.validateDisclosureSystem and
|
|
9
|
-
# corrected merge of pre-plugin code per LOGIUS
|
|
10
|
-
getattr(modelXbrl.modelManager.validateDisclosureSystem, "SBRNLplugin", False)):
|
|
11
|
-
#must read file in binary and return nothing to not replace standard loading
|
|
12
|
-
with open(filepath, 'rb') as fb:
|
|
13
|
-
startingBytes = fb.read(8)
|
|
14
|
-
if re.match(b"\\x00\\x00\\xFE\\xFF|\\xFF\\xFE\\x00\\x00|\\x2B\\x2F\\x76\\x38|\\x2B\\x2F\\x76\\x39|\\x2B\\x2F\\x76\\x2B|\\x2B\\x2F\\x76\\x2F|\\xDD\\x73\\x66\\x73|\\xEF\\xBB\\xBF|\\x0E\\xFE\\xFF|\\xFB\\xEE\\x28|\\xFE\\xFF|\\xFF\\xFE",
|
|
15
|
-
startingBytes):
|
|
16
|
-
modelXbrl.error("SBR.NL.2.1.0.09",
|
|
17
|
-
_("File MUST not start with a Byte Order Mark (BOM): %(filename)s"),
|
|
18
|
-
modelObject=modelXbrl, filename=mappedUri)
|
|
19
|
-
return None # must return None for regular document loading to continue
|