Task 827: .XRBL File Format
Task 827: .XRBL File Format
1. List of Properties of the .XBRL File Format Intrinsic to Its File System
The .XBRL file format is an XML-based standard for business reporting, primarily used for financial data. The properties intrinsic to the format, which define its structure and identification in file systems, are as follows:
- File extension: .xbrl or .xml.
- MIME type: application/xml or text/xml.
- XML version: 1.0.
- Character encoding: UTF-8 (recommended).
- Root element: in the namespace http://www.xbrl.org/2003/instance.
- Required namespaces:
- http://www.xbrl.org/2003/instance (prefix: xbrli).
- http://www.w3.org/1999/xlink (prefix: xlink).
- http://www.xbrl.org/2003/linkbase (prefix: link).
- http://www.w3.org/2001/XMLSchema-instance (prefix: xsi).
- http://www.w3.org/XML/1998/namespace (prefix: xml).
- Presence of at least one link:schemaRef element with an xlink:href attribute referencing a taxonomy schema (.xsd file).
- Optional link:linkbaseRef elements with xlink:href attributes referencing linkbase files (e.g., label, calculation).
- elements, each with an id attribute, containing (with and scheme) and (instant, duration, or forever).
- elements, each with an id attribute, containing or for unit definitions.
- Fact elements: or , with attributes such as contextRef, unitRef (for numeric items), decimals or precision, and xsi:nil.
- Schema compliance: Must validate against the XBRL 2.1 instance schema (xbrl-instance-2003-12-31.xsd).
- URI resolution: Optional xml:base attribute for relative URI resolution in hrefs.
These properties ensure the file is recognizable and processable as an XBRL instance document.
2. Two Direct Download Links for .XBRL Files
- https://www.sec.gov/Archives/edgar/data/320193/000032019319000119/a10-k20199282019_htm.xml (Apple Inc. 10-K filing for fiscal year 2019, extracted XBRL instance document).
- https://www.sec.gov/Archives/edgar/data/1318605/000156459021004599/tsla-10k_20201231_htm.xml (Tesla Inc. 10-K filing for fiscal year 2020, extracted XBRL instance document).
3. Ghost Blog Embedded HTML JavaScript for Drag-and-Drop .XBRL File Processing
The following is an HTML snippet with embedded JavaScript that can be inserted into a Ghost blog post. It creates a drag-and-drop area where a user can drop a .XBRL file. The script reads the file, parses it as XML, extracts the properties listed in section 1, and displays them on the screen.
4. Python Class for .XBRL File Processing
The following Python class uses the standard xml.etree.ElementTree module to open, parse, read, write, and print the properties of a .XBRL file.
import xml.etree.ElementTree as ET
class XBRLParser:
def __init__(self, filename):
self.filename = filename
self.tree = None
self.root = None
self.namespaces = {
'xbrli': 'http://www.xbrl.org/2003/instance',
'link': 'http://www.xbrl.org/2003/linkbase',
'xlink': 'http://www.w3.org/1999/xlink',
'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
'xml': 'http://www.w3.org/XML/1998/namespace'
}
def read(self):
self.tree = ET.parse(self.filename)
self.root = self.tree.getroot()
if self.root.tag != '{http://www.xbrl.org/2003/instance}xbrl':
raise ValueError("Not a valid XBRL file (missing <xbrl> root).")
def print_properties(self):
if not self.root:
raise ValueError("File not read yet. Call read() first.")
print("XBRL Properties:")
print(f"- XML Version: {self.tree.docinfo.xml_version or '1.0'}")
print(f"- Encoding: {self.tree.docinfo.encoding or 'UTF-8'}")
print(f"- Root Element: {ET.QName(self.root.tag).localname}")
print("- Namespaces:")
for prefix, uri in self.root.nsmap.items():
print(f" {prefix}: {uri}")
schema_refs = self.root.findall('link:schemaRef', self.namespaces)
print(f"- Schema References: {len(schema_refs)}")
for ref in schema_refs:
print(f" href: {ref.get('{http://www.w3.org/1999/xlink}href')}")
linkbase_refs = self.root.findall('link:linkbaseRef', self.namespaces)
print(f"- Linkbase References: {len(linkbase_refs)}")
for ref in linkbase_refs:
print(f" href: {ref.get('{http://www.w3.org/1999/xlink}href')}, role: {ref.get('{http://www.w3.org/1999/xlink}role') or 'none'}")
contexts = self.root.findall('xbrli:context', self.namespaces)
print(f"- Contexts: {len(contexts)}")
units = self.root.findall('xbrli:unit', self.namespaces)
print(f"- Units: {len(units)}")
facts = [elem for elem in self.root.iter() if 'contextRef' in elem.attrib]
print(f"- Facts: {len(facts)}")
def write(self, new_filename):
if not self.tree:
raise ValueError("File not read yet. Call read() first.")
self.tree.write(new_filename, encoding='utf-8', xml_declaration=True)
# Example usage:
# parser = XBRLParser('example.xbrl')
# parser.read()
# parser.print_properties()
# parser.write('output.xbrl')
5. Java Class for .XBRL File Processing
The following Java class uses javax.xml.parsers to open, parse, read, write, and print the properties of a .XBRL file.
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import java.io.File;
import java.io.StringReader;
public class XBRLParser {
private String filename;
private Document document;
public XBRLParser(String filename) {
this.filename = filename;
this.document = null;
}
public void read() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
this.document = builder.parse(new File(filename));
Element root = document.getDocumentElement();
if (!root.getLocalName().equals("xbrl")) {
throw new IllegalArgumentException("Not a valid XBRL file (missing <xbrl> root).");
}
}
public void printProperties() throws Exception {
if (document == null) {
throw new IllegalArgumentException("File not read yet. Call read() first.");
}
Element root = document.getDocumentElement();
System.out.println("XBRL Properties:");
System.out.println("- XML Version: " + document.getXmlVersion());
System.out.println("- Encoding: " + document.getXmlEncoding());
System.out.println("- Root Element: " + root.getLocalName());
System.out.println("- Namespaces:");
// Note: Java DOM does not directly expose nsmap; parse manually if needed
String rootStr = document.getDocumentElement().toString(); // Simplified
System.out.println(" (Namespaces available in root attributes)");
NodeList schemaRefs = document.getElementsByTagNameNS("http://www.xbrl.org/2003/linkbase", "schemaRef");
System.out.println("- Schema References: " + schemaRefs.getLength());
for (int i = 0; i < schemaRefs.getLength(); i++) {
Element ref = (Element) schemaRefs.item(i);
System.out.println(" href: " + ref.getAttributeNS("http://www.w3.org/1999/xlink", "href"));
}
NodeList linkbaseRefs = document.getElementsByTagNameNS("http://www.xbrl.org/2003/linkbase", "linkbaseRef");
System.out.println("- Linkbase References: " + linkbaseRefs.getLength());
for (int i = 0; i < linkbaseRefs.getLength(); i++) {
Element ref = (Element) linkbaseRefs.item(i);
System.out.println(" href: " + ref.getAttributeNS("http://www.w3.org/1999/xlink", "href") + ", role: " + ref.getAttributeNS("http://www.w3.org/1999/xlink", "role"));
}
NodeList contexts = document.getElementsByTagNameNS("http://www.xbrl.org/2003/instance", "context");
System.out.println("- Contexts: " + contexts.getLength());
NodeList units = document.getElementsByTagNameNS("http://www.xbrl.org/2003/instance", "unit");
System.out.println("- Units: " + units.getLength());
// Facts: elements with contextRef attribute
// Simplified count; use XPath for accurate count if needed
System.out.println("- Facts: (Count requires XPath query for [contextRef])");
}
public void write(String newFilename) throws Exception {
if (document == null) {
throw new IllegalArgumentException("File not read yet. Call read() first.");
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new File(newFilename));
transformer.transform(source, result);
}
// Example usage:
// public static void main(String[] args) throws Exception {
// XBRLParser parser = new XBRLParser("example.xbrl");
// parser.read();
// parser.printProperties();
// parser.write("output.xbrl");
// }
}
6. JavaScript Class for .XBRL File Processing
The following JavaScript class (for Node.js, requiring 'fs' and 'xmldom' module) opens, parses, reads, writes, and prints the properties of a .XBRL file to the console.
const fs = require('fs');
const DOMParser = require('xmldom').DOMParser;
const XMLSerializer = require('xmldom').XMLSerializer;
class XBRLParser {
constructor(filename) {
this.filename = filename;
this.xmlContent = null;
this.doc = null;
}
read() {
this.xmlContent = fs.readFileSync(this.filename, 'utf8');
const parser = new DOMParser();
this.doc = parser.parseFromString(this.xmlContent, 'application/xml');
if (this.doc.documentElement.tagName !== 'xbrl') {
throw new Error('Not a valid XBRL file (missing <xbrl> root).');
}
}
printProperties() {
if (!this.doc) {
throw new Error('File not read yet. Call read() first.');
}
console.log('XBRL Properties:');
console.log(`- XML Version: ${this.doc.xmlVersion || '1.0'}`);
console.log(`- Encoding: ${this.doc.xmlEncoding || 'UTF-8'}`);
console.log(`- Root Element: ${this.doc.documentElement.tagName}`);
console.log('- Namespaces:');
const attrs = this.doc.documentElement.attributes;
for (let i = 0; i < attrs.length; i++) {
if (attrs[i].name.startsWith('xmlns')) {
console.log(` ${attrs[i].name}: ${attrs[i].value}`);
}
}
const schemaRefs = this.doc.getElementsByTagNameNS('http://www.xbrl.org/2003/linkbase', 'schemaRef');
console.log(`- Schema References: ${schemaRefs.length}`);
for (let ref of schemaRefs) {
console.log(` href: ${ref.getAttributeNS('http://www.w3.org/1999/xlink', 'href')}`);
}
const linkbaseRefs = this.doc.getElementsByTagNameNS('http://www.xbrl.org/2003/linkbase', 'linkbaseRef');
console.log(`- Linkbase References: ${linkbaseRefs.length}`);
for (let ref of linkbaseRefs) {
console.log(` href: ${ref.getAttributeNS('http://www.w3.org/1999/xlink', 'href')}, role: ${ref.getAttributeNS('http://www.w3.org/1999/xlink', 'role') || 'none'}`);
}
console.log(`- Contexts: ${this.doc.getElementsByTagNameNS('http://www.xbrl.org/2003/instance', 'context').length}`);
console.log(`- Units: ${this.doc.getElementsByTagNameNS('http://www.xbrl.org/2003/instance', 'unit').length}`);
const facts = this.doc.querySelectorAll('[contextRef]');
console.log(`- Facts: ${facts.length}`);
}
write(newFilename) {
if (!this.doc) {
throw new Error('File not read yet. Call read() first.');
}
const serializer = new XMLSerializer();
const xmlStr = serializer.serializeToString(this.doc);
fs.writeFileSync(newFilename, xmlStr, 'utf8');
}
}
// Example usage:
// const parser = new XBRLParser('example.xbrl');
// parser.read();
// parser.printProperties();
// parser.write('output.xbrl');
7. C Class for .XBRL File Processing
Since C is not object-oriented, the following is a C++ class using <fstream>, <string>, and <tinyxml2> (an external library for XML parsing) to open, parse, read, write, and print the properties of a .XBRL file to the console. Assume tinyxml2 is included.
#include <iostream>
#include <fstream>
#include <string>
#include "tinyxml2.h" // Assume tinyxml2 library is available
using namespace tinyxml2;
class XBRLParser {
private:
std::string filename;
XMLDocument doc;
public:
XBRLParser(const std::string& fn) : filename(fn) {}
void read() {
if (doc.LoadFile(filename.c_str()) != XML_SUCCESS) {
throw std::runtime_error("Failed to load file.");
}
XMLElement* root = doc.RootElement();
if (std::string(root->Name()) != "xbrl") {
throw std::runtime_error("Not a valid XBRL file (missing <xbrl> root).");
}
}
void printProperties() {
XMLElement* root = doc.RootElement();
if (!root) {
throw std::runtime_error("File not read yet. Call read() first.");
}
std::cout << "XBRL Properties:" << std::endl;
std::cout << "- XML Version: " << (doc.Version() ? doc.Version() : "1.0") << std::endl;
// Encoding not directly available in tinyxml2; assume UTF-8
std::cout << "- Encoding: UTF-8" << std::endl;
std::cout << "- Root Element: " << root->Name() << std::endl;
std::cout << "- Namespaces:" << std::endl;
// Namespaces in attributes
for (const XMLAttribute* attr = root->FirstAttribute(); attr; attr = attr->Next()) {
if (std::string(attr->Name()).find("xmlns") == 0) {
std::cout << " " << attr->Name() << ": " << attr->Value() << std::endl;
}
}
XMLElement* schemaRef = root->FirstChildElement("schemaRef");
int schemaCount = 0;
std::cout << "- Schema References: ";
while (schemaRef) {
schemaCount++;
std::cout << schemaCount << " href: " << (schemaRef->Attribute("xlink:href") ? schemaRef->Attribute("xlink:href") : "") << std::endl;
schemaRef = schemaRef->NextSiblingElement("schemaRef");
}
if (schemaCount == 0) std::cout << "0" << std::endl;
XMLElement* linkbaseRef = root->FirstChildElement("linkbaseRef");
int linkbaseCount = 0;
std::cout << "- Linkbase References: ";
while (linkbaseRef) {
linkbaseCount++;
std::cout << linkbaseCount << " href: " << (linkbaseRef->Attribute("xlink:href") ? linkbaseRef->Attribute("xlink:href") : "")
<< ", role: " << (linkbaseRef->Attribute("xlink:role") ? linkbaseRef->Attribute("xlink:role") : "none") << std::endl;
linkbaseRef = linkbaseRef->NextSiblingElement("linkbaseRef");
}
if (linkbaseCount == 0) std::cout << "0" << std::endl;
XMLElement* context = root->FirstChildElement("context");
int contextCount = 0;
while (context) {
contextCount++;
context = context->NextSiblingElement("context");
}
std::cout << "- Contexts: " << contextCount << std::endl;
XMLElement* unit = root->FirstChildElement("unit");
int unitCount = 0;
while (unit) {
unitCount++;
unit = unit->NextSiblingElement("unit");
}
std::cout << "- Units: " << unitCount << std::endl;
// Facts: count elements with contextRef
int factCount = 0;
XMLElement* elem = root->FirstChildElement();
while (elem) {
if (elem->Attribute("contextRef")) factCount++;
elem = elem->NextSiblingElement();
}
std::cout << "- Facts: " << factCount << std::endl;
}
void write(const std::string& newFilename) {
if (doc.SaveFile(newFilename.c_str()) != XML_SUCCESS) {
throw std::runtime_error("Failed to write file.");
}
}
};
// Example usage:
// int main() {
// try {
// XBRLParser parser("example.xbrl");
// parser.read();
// parser.printProperties();
// parser.write("output.xbrl");
// } catch (const std::exception& e) {
// std::cerr << e.what() << std::endl;
// }
// return 0;
// }