Stuart Breckenridge

FATCA Metadata for Windows

Metadata Screenshot

I’ve been playing around with C# and Visual Studio recently and my test project was to build an app—in this case a Windows form—that took user data, validated it, and then created a correctly formatted XML file that could be used as part of annual FATCA submissions. As part of this learning process two technologies stood out as really impressive: XDocument and ClickOnce Deployment.

The XML file I wanted to create was pretty simple:

<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2014 rel. 2 (http://www.altova.com)-->
<FATCAIDESSenderFileMetadata xmlns="urn:fatca:idessenderfilemetadata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<FATCAEntitySenderId>000000.00000.TA.840</FATCAEntitySenderId>
	<FATCAEntityReceiverId>000000.00000.TA.124</FATCAEntityReceiverId>
	<FATCAEntCommunicationTypeCd>NTF</FATCAEntCommunicationTypeCd>
	<SenderFileId>000000.00000.TA.840_Payload.xml</SenderFileId>
	<FileFormatCd>XML</FileFormatCd>
	<BinaryEncodingSchemeCd>NONE</BinaryEncodingSchemeCd>
	<FileCreateTs>2015-06-30T00:00:00Z</FileCreateTs>
	<TaxYear>2014</TaxYear>
	<FileRevisionInd>false</FileRevisionInd>
</FATCAIDESSenderFileMetadata>

Creating this on a Mac using a technology I’m familiar with—NSXMLDocument—is simple, if overly verbose:

func generateXMLFile() -> NSXMLDocument
{
    // Header
    let xmlFile = NSXMLDocument()
    xmlFile.version = "1.0"
    xmlFile.characterEncoding = "UTF-8"
    xmlFile.standalone = true
    xmlFile.addChild(NSXMLNode.commentWithStringValue("FATCA Report") as! NSXMLNode)
    
    // Root Element
    xmlFile.setRootElement(NSXMLElement(name: "FATCAIDESSenderFileMetadata"))
    xmlFile.rootElement()?.addNamespace(NSXMLNode.namespaceWithName("", stringValue: "urn:fatca:idessenderfilemetadata") as! NSXMLNode)
    xmlFile.rootElement()?.addNamespace(NSXMLNode.namespaceWithName("xsi", stringValue: "http://www.w3.org/2001/XMLSchema-instance") as! NSXMLNode)
    
    // Child Elements
    xmlFile.rootElement()?.addChild(NSXMLElement.elementWithName("FATCAEntitySenderId", stringValue: "000000.00000.TA.840") as! NSXMLNode)
    xmlFile.rootElement()?.addChild(NSXMLElement.elementWithName("FATCAEntityReceiverId", stringValue: "000000.00000.TA.124") as! NSXMLNode)
    xmlFile.rootElement()?.addChild(NSXMLElement.elementWithName("FATCAEntCommunicationTypeCd", stringValue: "NTF") as! NSXMLNode)
    xmlFile.rootElement()?.addChild(NSXMLElement.elementWithName("SenderFileId", stringValue: "000000.00000.TA.840_Payload.xml") as! NSXMLNode)
    xmlFile.rootElement()?.addChild(NSXMLElement.elementWithName("FileFormatCd", stringValue: "XML") as! NSXMLNode)
    xmlFile.rootElement()?.addChild(NSXMLElement.elementWithName("BinaryEncodingSchemeCd", stringValue: "NONE") as! NSXMLNode)
    xmlFile.rootElement()?.addChild(NSXMLElement.elementWithName("FileCreateTs", stringValue: "2015-06-30T00:00:00Z") as! NSXMLNode)
    xmlFile.rootElement()?.addChild(NSXMLElement.elementWithName("TaxYear", stringValue: "2014") as! NSXMLNode)
    xmlFile.rootElement()?.addChild(NSXMLElement.elementWithName("FileRevisionInd", stringValue: "false") as! NSXMLNode)
    
    xmlFile.XMLStringWithOptions(NSXMLNodePrettyPrint)
    return xmlFile
}

Now, compare that to XDocument:

XDocument generateXMLFile()
        {
			XNamespace metaNS = "uri:fatca:idessenderfilemetadata"
			
            XDocument xmlFile = new XDocument(
                new XComment("FATCA Report"),
            new XElement(metaNS + "FATCAIDESSenderFileMetadata",
				new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
                new XElement(metaNS + "FATCAEntitySenderId", "000000.00000.TA.840"),
                new XElement(metaNS + "FATCAEntityReceiverId", "000000.00000.TA.124"),
                new XElement(metaNS + "FATCAEntCommunicationTypeCd", "NTF"),
                new XElement(metaNS + "SenderFileId", "000000.00000.TA.840_Payload.xml"),
                new XElement(metaNS + "FileFormatCd","XML"),
                new XElement(metaNS + "BinaryEncodingSchemeCd","NONE"),
                new XElement(metaNS + "FileCreateTs", "2015-06-30T00:00:00Z"),
                new XElement(metaNS + "TaxYear", "2014"),
                new XElement(metaNS + "FileRevisionInd", "false"),
                )
                );
            xmlFile.Declaration =  new XDeclaration("1.0", "utf-8", "true");
			
			return xmlFile;
        }

XDocument, in comparison to NSXMLDocument, is both simpler and more concise. However, I think Swift itself also contributes to the complexity with constant forced as! conversions for each element. It’s generally very untidy.

With the app built, I started looking at how it could be deployed and immediately came across ClickOnce. ClickOnce is an easy to use deployment technology that lets you publish self-updating applications. For this app, I’ve chosen to deploy via my website. It can be installed via the link at the end of this article. Despite ClickOnce ease of use, the issue I’ve found is with Windows SmartScreen which prevents the app being installed until it’s built up enough reputation. This is somewhat annoying considering the app is code signed (see the note at the end of this post).

The app is open source and available on GitHub. Or you can simply install it by clicking the button below.

Install Now User Guide


Code Signing: You may see installation warnings; however, as long as you see my name in the Publisher section (below), you can be almost sure that the code hasn’t been tampered with.


— Supported by —