The following email came into the Gepsio email inbox not long ago:
I upgraded to your latest release btw but it looks like the Segment object was removed. How do I access Dimensions and Segments now?
The user had been using the Sep 2013 CTP [version 184.108.40.206] and had been using it to write code like this:
// this item has a dimension (grouped)
if (item.ContextRef.Segment != null)
foreach (System.Xml.XmlNode node in item.ContextRef.Segment)
//Insert_Dimension(FactItemID, node.Attributes["dimension"].Value, node.InnerText);
ddi.NewRow(FactItemID, node.Attributes["dimension"].Value, node.InnerText);
The short answer is that – oops! – the Segment property was moved from public visibility to internal visibility in the Nov 2014 CTP [220.127.116.11], and that change was retained in the May 2015 CTP [18.104.22.168]. It will be moved back to public visibility in the next CTP, but an explanation for the change is in order.
The Segment Property in the Sep 2013 CTP
In the Sep 2013 CTP, the public Segment property was a property of the Context class. It was of type System.Xml.XmlNode and was documented as follows:
The segment node defined for this context. If this context was not marked up with a segment node, then this property will return null.
This property was made available in support of section 22.214.171.124 of the XBRL 2.1 specification, which describes an optional <segment> child element of a <context> element:
The <segment> element is an optional container for additional mark-up that the preparer of an XBRL Instance SHOULD use to identify the business segment more completely in cases where the Entity identifier is insufficient. In general, the content of a <segment> will be specific to the purpose of the XBRL instance. Elements contained by the <segment> element MUST NOT be defined in the http://www.xbrl.org/2003/instance namespace. Also, they MUST NOT be in the substitution group for elements defined in the http://www.xbrl.org/2003/instance namespace. The <segment> element MUST NOT be empty.
The XBRL 2.1 specification does not associate any semantics with the <segment> element; therefore, Gepsio could not define an object model around this element, since it is documented as an optional container containing zero or more elements whose semantics were presumably documented elsewhere. Therefore, Gepsio could only expose the element, if it existed, as a generic XmlNode.
Introducing the Interface-Based XML Layer
On 18 July 2014, a changeset was checked in which changed Gepsio’s relationship to the .NET 3.5 XML DOM classes. This change was first published in a build in the Nov 2014 CTP and continued on in the May 2015 CTP. This change removed Gepsio’s direct dependency on the .NET 3.5 XML DOM classes and, instead, moved the support behind a set of internally-defined interfaces. The change introduced interfaces to handle all of the XML work, as well as classes that implemented the interface using the .NET 3.5 XML DOM classes. So, with this design, instead of Gepsio calling something like XmlDocument.Load() to load an XBRL document instance, it called an interface method called IDocument.Load(). The IDocument.Load() interface implementation called XmlDocument.Load() in its implementation.
The rationale behind moving Gepsio’s XML layer behind an interface was to make it easier to support other XML implementations in the future. The future of Gepsio, and its possible reach beyond purely .NET and possibly into other areas, whether it be as a Portable Class Library, as a library that would support Xamarin, or as a library that would support the Universal Windows Platform, means that Gepsio may need to be modified at its lowest level XML layer. For example, The Portable Class Library does not support the .NET 3.5 XML DOM classes. Instead, it supports only the LINQ-to-XML classes. Once XML is loaded, Gepsio is pretty portable, but the XML layer could potentially be a porting problem down the road should the XML runtime need to change.
Moving all of Gepsio’s low level XML needs behind an interface, and implementing the interface in a set of classes that Gepsio would actually be using, makes it easier to change the XML layer later on, should the need arise, without disturbing the rest of the Gepsio code base. Moving, for example, from the .NET 3.5 XML DOM classes to LINQ-to-XML would be a (theoretically) simple matter of implementing the internal XML interfaces in classes that used LINQ-to-XML. Gepsio’s higher levels of code – the XBRL semantics – would not need to change.
Interfaces and the Segment Property
The issue with the interface implementation with regards to the Segment property is that things like System.Xml.XmlNode, which were originally exposed as the type of the Segment property, are now behind an interface. With the XML interface design, Gepsio no longer sees a System.Xml.XmlNode object directly. Instead, it sees an internally-defined INode interface, and System.Xml.XmlNode is hidden behind the implementation of INode. With the interface design change, the Segment property in question would need to have its type changed from System.Xml.XmlNode to INode. The problem there is that INode is defined internally by Gepsio, and external callers, such as the code shown above, have no knowledge of INode. Failing that understanding, the Segment property could not be exposed, so the property was moved to be private in the Nov 2014 CTP.
The Road Forward
Since folks are, in fact, using the Segment property for Dimensions work (and, failing Gepsio’s first-party support for Dimensions, which needs to get on the project roadmap), then the Segment property will once again need to go public. Work will, therefore, progress in getting the XML interfaces documented so that people can use an internally-defined INode implementation to do work with segment nodes. This work is underway now.