An experiment in W3C spec overlap: using SVG, MathML, XML, RDF to represent company accounts in the Web.
by Dan Brickley (W3C/ILRT), April 2002
Company Accounts provide an interesting Semantic Web application scenario, since there are a number of issues associated with representing accounting information in the Web that require the use of multiple W3C specifications.
Status: This is a work in progress. Some sample data (company report summaries, RDFS schema) is available, along with some exerimental RDF-Logic rules. The MathML and SVG ideas are all vapourware at this stage. Help welcomed!
We can use MathML to represent numeric information (for presentation and for content interchange), we can use XML Schemas and DTDs to represent document formats for interchange; or RDF Schemas and Web Ontologies to represent the structure and constraints associated with the information modelling that underpins such documents. SVG provides an excellent format, again written in XML, for the exchange of diagramatic representation (eg. charts, figures) derrived from copmany account information. RDF can be used to merge information about companies from multiple sources, and RDF rule and inference systems (perhaps combined with MathML) may be useful for capturing the basic formulae that underpin company accounts. The challenge is to combine all these relevant components into a useful, understandable and maintainable whole.
This experiment begins with some sample data from the Biz/ed Web site.
The idea is to make some data available (see reports.xml and original text format), and then show how MathML, RDF, SVG etc representations overlap. For now, all we have is the RDF version, and some text (and Perl) representations of how the different company report properties are related.
It would be good to...
Thanks to Sean and Aaron from #rdfig irc chat)
A writeup of this work isn't integrated here yet, but some test queries, sample output etc are available nearby in the Web. The example query uses the CWM RDF-Logic system, and in particular its math(s) support, to represent relationships between the notion of 'fc:sr' and 'fc:spe' and 'fc:noe'.
(expanded explanation would go nicely here)
The following definitions are used by the Biz/ed online company report profiler. They express relationships amongst the various measures used in company accounts.
Calculated values: RNA: Return on Net Assests = Operating Profit/Net Assets PM: Profit Margin = Operating Profit/Sales Revenue AT: Asset Turnover = Sales/Net Assets SPE: Sales per Employee = Sales/Number of Employees OPPE: Operating Profit per Employee = Operating Profit/Number of Employees NUKSR: Non UK Sales = Non UK Sales/Total Sales CR: Current Ratio = Current Assets/Current Liabilites$Calc{'ATR'}="&ATR()"; # ATR: ???= (Current Assets - Stocks) /Current Liabilities DD: Debtor Days = Debtors/Sales/365 SD: Stock Days = Stocks/Cost of Sales/365 G: Gearing = Long term Liabilities/Shareholders Funds IC: Interest Cover = Operating Profit / Interest DC: Dividend Cover = Profit Attributable / Dividends Paid CA: Current Assets SOURCE: Company Name YEAR: Year of report
The following is a draft (see rdf version) of a schema that captures the basic properties. TODO: check to see this is complete and consistent with the test data we have.
ca: Current Assets - Total cas: Current Assets - Stocks cad: Current Assets - Debtors cac: Current Assets - Cash etc. cl: Current Liabilities nwc: Net Working Capital ltl: Long Term Liabilities na: Net Assets sf: Shareholder's Funds eps: Earnings Per Share dps: Dividends Per Share rna: Return on Net Assets pm: Profit Margin at: Asset Turnover spe: Sales Per Employee oppe: Operating Profit per Employee nuksr: Non UK Sales percent cr: Current Ratio atr: Acid Test Ratio dd: Debtor Days sd: Stock Days g: Gearing ic: Interest Cover dc: Dividend Cover
<rdf:Property rdf:about="http://xmlns.com/foaf/corp#ltl" rdfs:label="ltl" rdfs:comment="Long Term Liabilities"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#na" rdfs:label="na" rdfs:comment="Net Assets"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#nuksr" rdfs:label="nuksr" rdfs:comment="Non UK Sales percent"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#nwc" rdfs:label="nwc" rdfs:comment="Net Working Capital"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#atr" rdfs:label="atr" rdfs:comment="Acid Test Ratio"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#cas" rdfs:label="cas" rdfs:comment="Current Assets - Stocks"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#spe" rdfs:label="spe" rdfs:comment="Sales Per Employee"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#dps" rdfs:label="dps" rdfs:comment="Dividends Per Share"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#g" rdfs:label="g" rdfs:comment="Gearing"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#eps" rdfs:label="eps" rdfs:comment="Earnings Per Share"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#ca" rdfs:label="ca" rdfs:comment="Current Assets - Total"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#sd" rdfs:label="sd" rdfs:comment="Stock Days"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#dc" rdfs:label="dc" rdfs:comment="Dividend Cover"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#dd" rdfs:label="dd" rdfs:comment="Debtor Days"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#sf" rdfs:label="sf" rdfs:comment="Shareholder's Funds"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#pm" rdfs:label="pm" rdfs:comment="Profit Margin"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#cac" rdfs:label="cac" rdfs:comment="Current Assets - Cash etc."/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#cl" rdfs:label="cl" rdfs:comment="Current Liabilities"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#cad" rdfs:label="cad" rdfs:comment="Current Assets - Debtors"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#ic" rdfs:label="ic" rdfs:comment="Interest Cover"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#at" rdfs:label="at" rdfs:comment="Asset Turnover"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#rna" rdfs:label="rna" rdfs:comment="Return on Net Assets"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#cr" rdfs:label="cr" rdfs:comment="Current Ratio"/> <rdf:Property rdf:about="http://xmlns.com/foaf/corp#oppe" rdfs:label="oppe" rdfs:comment="Operating Profit per Employee"/>
The following extracted from the Perl code and the headings from the data file.
SOURCE: Company Name YEAR: Year of report CAS: CAD CAC CL NWC LTL NA SF SR COS OP INT PAT DP RP NE NUKS SFO RNA PM AT SPE OPPE NUKST SPSF CR ATR DD SD G IC EPS DPS DC
sub RNA { return("RNA") if($inHeader); return("*") if ($elements[$Index{'NA'}]==0); # NULL trap return(sprintf("%.2f",$elements[$Index{'OPOA'}]/$elements[$Index{'NA'}]*100)); } sub PM { return("PM") if($inHeader); return("*") if ($elements[$Index{'SR'}]==0); # NULL trap return(sprintf("%.2f",$elements[$Index{'OPOA'}]/$elements[$Index{'SR'}]*100)); } sub AT { return("AT") if($inHeader); return("*") if ($elements[$Index{'NA'}]==0); # NULL trap return(sprintf("%.2f",$elements[$Index{'SR'}]/$elements[$Index{'NA'}])); } sub SPE { return("SPE") if($inHeader); return("*") if ($elements[$Index{'NOE'}]==0); # NULL trap return(sprintf("%.2f",$elements[$Index{'SR'}]/$elements[$Index{'NOE'}]*1000000)); } sub OPPE { return("OPPE") if($inHeader); return("*") if ($elements[$Index{'NOE'}]==0); # NULL trap return(sprintf("%.2f",$elements[$Index{'OPOA'}]/$elements[$Index{'NOE'}]*1000000)); } sub NUKSR { return("NUKSR") if($inHeader); return("*") if ($elements[$Index{'SR'}]==0); # NULL trap return(sprintf("%.2f",$elements[$Index{'NUKSV'}]/$elements[$Index{'SR'}]*100)); } sub CR { return("CR") if($inHeader); return("*") if ($elements[$Index{'CL'}]==0); # NULL trap return(sprintf("%.2f",&CA()/$elements[$Index{'CL'}])); } sub ATR { return("ATR") if($inHeader); return("*") if ($elements[$Index{'SR'}]==0); # NULL trap return(sprintf("%.2f",($elements[$Index{'CAD'}]+$elements[$Index{'CAC'}])/$elements[$Index{'CL'}])); } sub CA { return("CA") if($inHeader); return(sprintf("%.2f",$elements[$Index{'CAS'}]+$elements[$Index{'CAD'}]+$elements[$Index{'CAC'}])); } sub DD { return("DD") if($inHeader); return("*") if ($elements[$Index{'SR'}]==0); # NULL trap return(sprintf("%.2f",($elements[$Index{'CAD'}]*100000/$elements[$Index{'SR'}])/365)); } sub SD { return("SD") if($inHeader); return("*") if ($elements[$Index{'SR'}]==0); # NULL trap return(sprintf("%.2f",($elements[$Index{'CAS'}]*100000/$elements[$Index{'COS'}])/365)); } sub G { return("G") if ($inHeader); return("*") if ($elements[$Index{'SF'}]==0); # NULL trap return(sprintf("%.2f",$elements[$Index{'LTL'}]/$elements[$Index{'SF'}]*100)); } sub IC { return("IC") if ($inHeader); return("*") if ($elements[$Index{'I'}]==0); # NULL trap return(sprintf("%.2f",$elements[$Index{'OPOA'}]/$elements[$Index{'I'}])); } sub DC { return("DC") if ($inHeader); return("*") if ($elements[$Index{'DP'}]==0); # NULL trap return(sprintf("%.2f",$elements[$Index{'PATC'}]/$elements[$Index{'DP'}])); }