Skip to content

Working with XBRL Facts

Jeff Ferguson edited this page Oct 9, 2017 · 2 revisions

At the heart of any XBRL instance is a construct called a fact. A fact manages a value being described in the instance. Conceptually, an XBRL instance is a big data dictionary of facts.

Facts

Within Gepsio, each fragment contains a list of facts. Facts are found in a property of an XBRL fragment called Facts. Each fact is described in an object of a class called JeffFerguson.Gepsio.Fact. Every fact has a name:

using JeffFerguson.Gepsio;
using System;

namespace Facts
{
    class Program
    {
        static void Main(string[] args)
        {
            var xbrlDoc1 = new XbrlDocument();
            xbrlDoc1.Load(@"..\..\JeffFerguson.Gepsio.Test\XBRL-CONF-2014-12-10\Common\300-instance\301-01-IdScopeValid.xml");
            ShowFactsInDocument(xbrlDoc1);
        }

        private static void ShowFactsInDocument(XbrlDocument doc)
        {
            foreach (var currentFragment in doc.XbrlFragments)
            {
                ShowFactsInFragment(currentFragment);
            }
        }

        private static void ShowFactsInFragment(XbrlFragment currentFragment)
        {
            foreach(var currentFact in currentFragment.Facts)
            {
                ShowFact(currentFact);
            }
        }

        private static void ShowFact(Fact fact)
        {
            Console.WriteLine($"FACT {fact.Name}");
        }
    }
}

Types of Facts

The XBRL specification describes two kinds of facts:

  • Items, which are facts with a single value
  • Tuples, which are facts with a collection of items, giving the tuple a character of a multi-value fact

Most XBRL instances use items exclusively, although tuples can be found in XBRL instances as well. Well-written code will honor both possibilities.

Items

Within Gepsio, items are described in a class called JeffFerguson.Gepsio.Item, which is derived from JeffFerguson.Gepsio.Fact. If a Fact object can be cast as an Item object, then the fact is, in fact, an item. For items, the value of the item is in a Item property called Value:

using JeffFerguson.Gepsio;
using System;

namespace Facts
{
    class Program
    {
        static void Main(string[] args)
        {
            var xbrlDoc1 = new XbrlDocument();
            xbrlDoc1.Load(@"..\..\JeffFerguson.Gepsio.Test\XBRL-CONF-2014-12-10\Common\300-instance\301-01-IdScopeValid.xml");
            ShowFactsInDocument(xbrlDoc1);

            var xbrlDoc2 = new XbrlDocument();
            xbrlDoc2.Load(@"..\..\JeffFerguson.Gepsio.Test\XBRL-CONF-2014-12-10\Common\300-instance\306-02-RequiredInstanceTupleValid.xml");
            ShowFactsInDocument(xbrlDoc2);
        }

        private static void ShowFactsInDocument(XbrlDocument doc)
        {
            foreach (var currentFragment in doc.XbrlFragments)
            {
                ShowFactsInFragment(currentFragment);
            }
        }

        private static void ShowFactsInFragment(XbrlFragment currentFragment)
        {
            foreach(var currentFact in currentFragment.Facts)
            {
                ShowFact(currentFact);
            }
        }

        private static void ShowFact(Fact fact)
        {
            Console.WriteLine($"FACT {fact.Name}");
            if (fact is Item)
            {
                ShowItem(fact as Item);
            }
        }

        private static void ShowItem(Item item)
        {
            Console.WriteLine("\tType     : Item");
            Console.WriteLine($"\tValue    : {item.Value}");
        }
    }
}

Tuples

Within Gepsio, tuples are described in a class called JeffFerguson.Gepsio.Tuple, which is also derived from JeffFerguson.Gepsio.Fact. If a Fact object can be cast as an Tuple object, then the fact is, in fact, a tuple. For tuples, which manages a collection of values, the class maintains a list of facts in a property called Facts:

using JeffFerguson.Gepsio;
using System;

namespace Facts
{
    class Program
    {
        static void Main(string[] args)
        {
            var xbrlDoc1 = new XbrlDocument();
            xbrlDoc1.Load(@"..\..\JeffFerguson.Gepsio.Test\XBRL-CONF-2014-12-10\Common\300-instance\301-01-IdScopeValid.xml");
            ShowFactsInDocument(xbrlDoc1);

            var xbrlDoc2 = new XbrlDocument();
            xbrlDoc2.Load(@"..\..\JeffFerguson.Gepsio.Test\XBRL-CONF-2014-12-10\Common\300-instance\306-02-RequiredInstanceTupleValid.xml");
            ShowFactsInDocument(xbrlDoc2);
        }

        private static void ShowFactsInDocument(XbrlDocument doc)
        {
            foreach (var currentFragment in doc.XbrlFragments)
            {
                ShowFactsInFragment(currentFragment);
            }
        }

        private static void ShowFactsInFragment(XbrlFragment currentFragment)
        {
            foreach(var currentFact in currentFragment.Facts)
            {
                ShowFact(currentFact);
            }
        }

        private static void ShowFact(Fact fact)
        {
            Console.WriteLine($"FACT {fact.Name}");
            if (fact is Item)
            {
                ShowItem(fact as Item);
            }
            else if (fact is JeffFerguson.Gepsio.Tuple)
            {
                ShowTuple(fact as JeffFerguson.Gepsio.Tuple);
            }
        }

        private static void ShowItem(Item item)
        {
            Console.WriteLine("\tType     : Item");
            Console.WriteLine($"\tNamespace: {item.Namespace}");
            Console.WriteLine($"\tValue    : {item.Value}");
        }

        private static void ShowTuple(JeffFerguson.Gepsio.Tuple tuple)
        {
            Console.WriteLine("\tType     : Tuple");
            foreach(var currentFact in tuple.Facts)
            {
                ShowFact(currentFact);
            }
        }
    }
}

Finding Facts By Name or ID

The Facts property on an XbrlFragment object exposes some helper methods to quickly find a specific fact. For example, if you are looking for a specific fact, and you know its name, you can call a method called GetFactByName():

var factFound = currentFragment.Facts.GetFactByName(factName);

If the XBRL fragment has more than one fact with the same name, then you can call GetFactsByName() to return a list of facts matching the supplied fact name:

var listOfFactsFound = currentFragment.Facts.GetFactsByName(factName);

If you know a fact's ID, then you can call GetFactByID() or GetFactsByID() on an XbrlFragment object to find a fact, or set of facts, by their ID.