This discussion is locked
Will Griffith

Q: anyone working on...

anyone working on a Filemaker module for FCS?

Something that reads and writes metadata?

It would be great to set up job tracking in Filemaker with
a FCS database connected.

MacPro(s), Mac OS X (10.6.4), FCS, Maya, CS5

Posted on Oct 29, 2010 10:16 AM

Close

Q: anyone working on...

  • All replies
  • Helpful answers

  • by Jim Mellor,Solvedanswer

    Jim Mellor Jim Mellor Oct 29, 2010 5:00 PM in response to Will Griffith
    Level 1 (15 points)
    Oct 29, 2010 5:00 PM in response to Will Griffith
    There are a few ways of doing this. Perhaps the simplest to implement is to use XML files exchanged between applications. Conveniently Filemaker allows for XML import and export to be made using XSLT files which can be used to translate from one type of XML to another. These action can be scripted to ensure the process remains automated. Filemaker can also talk to AppleScript which is handy to perform any housekeeping duties, like clearing out watched folders.

    Below are some templates I used to do exactly this with an Artbox system and a Filemaker job management system. Save them as plain text files with the extension .xslt

    When exporting from Filemaker to Final Cut Server XML use the *Export Records...* function and specify XML. When asked to, use the fmp-fcsvr.xlst template you just created.

    You will need to ensure that you have the asset ID in a field somewhere on your FMP database. Without this you don't have a UID to sync the data. Make sure its the first column you export, the XSLT looks for that colum to form the asset reference in the XML file. The exported xml file should be dropped into a watched folder with an XML read response. Make sure you test this on a backup system before you go live, this could modify or delete your precious metadata if something goes wrong.

    fmp-fcsvr.xlst

    (begin)
    *<?xml version="1.0" encoding="UTF-8"?>*
    *<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fmp="http://www.filemaker.com/fmpxmlresult" version="1.0" exclude-result-prefixes="fmp">*
    *<xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>*
    *<!-- *
    *XML stylesheet to format FMPXMLRESULT XML exported from Filemaker to FinalCutServer/Artbox*
    *Asset setMd XML (see example below).*

    *2007 Jim Mellor*

    *Note: FileMaker XML must contain the Asset ID field as the first value of*
    *each record (ie the first column of each row) for this template to work.*

    *<?xml version="1.0"?>*
    <FinalCutServer>
    *<request reqId="setMd" entityId="/asset/38215">*
    <params>
    *<mdValue fieldName="Asset ID" dataType="integer">38215</mdValue>*
    *<mdValue fieldName="Whatever" dataType="string">This is your data</mdValue>*
    *<mdValue fieldName="Client" dataType="string">Super Company</mdValue>*
    *<mdValue fieldName="Brand" dataType="string">Blue Wavey Gel</mdValue>*
    *<mdValue fieldName="Product" dataType="string">Housebase April Campaign</mdValue>*
    *<mdValue fieldName="Title" dataType="string">Etc etc</mdValue>*
    </params>
    </request>
    </FinalCutServer>

    -->
    <!--
    *Root match template*
    -->
    *<xsl:template match="fmp:FMPXMLRESULT">*
    <FinalCutServer>
    *<xsl:for-each select="fmp:RESULTSET/fmp:ROW">*
    *<xsl:call-template name="request">*
    *<xsl:with-param name="row" select="position()"/>*
    </xsl:call-template>
    </xsl:for-each>
    </FinalCutServer>
    </xsl:template>
    *<xsl:template name="getEntityId">*
    *<xsl:param name="row"/>*
    *<xsl:variable name="entId">*
    *<xsl:value-of select="normalize-space(/fmp:FMPXMLRESULT/fmp:RESULTSET/fmp:ROW[position()=$row ]/fmp:COL[position()=1])"/>*
    </xsl:variable>
    *<xsl:variable name="prefix">*
    <xsl:text>/asset/</xsl:text>
    </xsl:variable>
    *<xsl:value-of select="concat($prefix, $entId)"/>*
    </xsl:template>
    *<xsl:template name="typeTranslator">*
    *<xsl:param name="fmpType"/>*
    <xsl:choose>
    *<xsl:when test="$fmpType = 'TEXT'">*
    <xsl:text>string</xsl:text>
    </xsl:when>
    *<xsl:when test="$fmpType = 'NUMBER'">*
    <xsl:text>integer</xsl:text>
    </xsl:when>
    *<xsl:when test="$fmpType = 'BOOLEAN'">*
    <xsl:text>bool</xsl:text>
    </xsl:when>
    *<xsl:when test="$fmpType = 'DATE'">*
    <xsl:text>dateTime</xsl:text>
    </xsl:when>
    </xsl:choose>
    </xsl:template>
    *<xsl:template name="request">*
    *<xsl:param name="row"/>*
    <request>
    *<xsl:attribute name="reqId">*
    <xsl:text>setMd</xsl:text>
    </xsl:attribute>
    *<xsl:attribute name="entityId">*
    *<xsl:call-template name="getEntityId">*
    *<xsl:with-param name="row" select="position()"/>*
    </xsl:call-template>
    </xsl:attribute>
    <params>
    *<xsl:for-each select="./fmp:COL">*
    *<xsl:call-template name="mdValue">*
    *<xsl:with-param name="col" select="position()"/>*
    *<xsl:with-param name="row" select="$row"/>*
    </xsl:call-template>
    </xsl:for-each>
    </params>
    </request>
    </xsl:template>
    *<xsl:template name="mdValue">*
    *<xsl:param name="col"/>*
    *<xsl:param name="row"/>*
    <mdValue>
    *<xsl:attribute name="fieldName">*
    *<xsl:value-of select="/fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD[$col]/@NAME"/>*
    </xsl:attribute>
    *<xsl:attribute name="dataType">*
    * <xsl:call-template name="typeTranslator">*
    *<xsl:with-param name="fmpType" select="/fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD[$col]/@TYPE"/>*
    </xsl:call-template>
    </xsl:attribute>
    *<xsl:value-of select="normalize-space(/fmp:FMPXMLRESULT/fmp:RESULTSET/fmp:ROW[position()=$row ]/fmp:COL[position()=$col])"/>*
    </mdValue>
    </xsl:template>
    </xsl:stylesheet>
    (end)


    Now, the other way! To send from Final Cut Server to FMP you need to *Import Records...* > *XML Data Source*. Tick use *XSL style sheet* and use the xslt file below. Your source files will come from an XML Write response from FCSvr. Typically this could be triggered on asset modification.

    fcsvr-fmp.xslt

    (begin)
    *<?xml version="1.0" encoding="UTF-8"?>*
    *<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.filemaker.com/fmpxmlresult" version="1.0">*
    *<!-- *
    *XML stylesheet to format FCSvr/Artbox Asset getMdReply XML to Filemaker FMPXMLRESULT.*

    *2007 Jim Mellor*

    *Note: If importing a combined bunch of entities, the first will define the*
    *fields imported into Filemaker and their import order. For this reason it is*
    *important to ensure that your Artbox getMdReply/entity entries contains the*
    *same metadata fields in the same order.*
    -->

    <!--
    *Root match template*
    -->
    *<xsl:template match="/">*
    *<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">*
    <ERRORCODE>0</ERRORCODE>
    *<PRODUCT BUILD="" NAME="" VERSION=""/>*
    *<DATABASE DATEFORMAT="M/d/yyyy" LAYOUT="" NAME="" RECORDS="{count(//)}" TIMEFORMAT="h:mm:ss a"/>*
    *<xsl:call-template name="METADATA"/>*
    *<xsl:call-template name="RESULTSET"/>*
    </FMPXMLRESULT>
    </xsl:template>
    *<xsl:template name="METADATA">*
    <METADATA>
    *<xsl:for-each select="/artbox/getMdReply/entity[1]/metadata/mdValue">*
    <FIELD>
    *<xsl:attribute name="EMPTYOK">YES</xsl:attribute>*
    *<xsl:attribute name="MAXREPEAT">1</xsl:attribute>*
    *<xsl:attribute name="NAME">*
    *<xsl:value-of select="@fieldName"/>*
    </xsl:attribute>
    *<xsl:attribute name="TYPE">*
    *<xsl:call-template name="typeTranslator">*
    *<xsl:with-param name="abType" select="@dataType"/>*
    </xsl:call-template>
    </xsl:attribute>
    </FIELD>
    </xsl:for-each>
    </METADATA>
    </xsl:template>
    *<xsl:template name="typeTranslator">*
    *<xsl:param name="abType"/>*
    <xsl:choose>
    *<xsl:when test="$abType = 'string'">*
    <xsl:text>TEXT</xsl:text>
    </xsl:when>
    *<xsl:when test="$abType = 'integer'">*
    <xsl:text>NUMBER</xsl:text>
    </xsl:when>
    *<xsl:when test="$abType = 'bool'">*
    <xsl:text>TEXT</xsl:text>
    </xsl:when>
    *<xsl:when test="$abType = 'dateTime'">*
    <xsl:text>DATE</xsl:text>
    </xsl:when>
    *<xsl:when test="$abType = 'coords'">*
    <xsl:text>TEXT</xsl:text>
    </xsl:when>
    *<xsl:when test="$abType = 'int64'">*
    <xsl:text>NUMBER</xsl:text>
    </xsl:when>
    *<xsl:when test="$abType = 'timecode'">*
    <xsl:text>TEXT</xsl:text>
    </xsl:when>
    </xsl:choose>
    </xsl:template>
    *<xsl:template name="RESULTSET">*
    <RESULTSET>
    *<xsl:attribute name="FOUND">*
    *<xsl:value-of select="count(/artbox/getMdReply/entity)"/>*
    </xsl:attribute>
    *<xsl:for-each select="/artbox/getMdReply/entity/">
    <ROW>
    *<xsl:attribute name="MODID">0</xsl:attribute>*
    *<xsl:attribute name="RECORDID">0</xsl:attribute>*
    *<xsl:for-each select="mdValue">*
    <COL>
    <DATA>
    *<xsl:value-of select="."/>*
    </DATA>
    </COL>
    </xsl:for-each>
    </ROW>
    </xsl:for-each>
    </RESULTSET>
    </xsl:template>
    </xsl:stylesheet>
    (end)

    Hope this helps your cause.
  • by Will Griffith,

    Will Griffith Will Griffith Nov 1, 2010 5:32 AM in response to Jim Mellor
    Level 1 (65 points)
    Nov 1, 2010 5:32 AM in response to Jim Mellor
    Thank you Jim. We will give this a try.
  • by Jim Mellor,

    Jim Mellor Jim Mellor Nov 1, 2010 5:58 AM in response to Will Griffith
    Level 1 (15 points)
    Nov 1, 2010 5:58 AM in response to Will Griffith
    Cool, good luck with that. I just realised that the formatting was all over the place, here are the files again using the forum's code tag:

    fmp-fcsvr.xslt


    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fmp="http://www.filemaker.com/fmpxmlresult" version="1.0" exclude-result-prefixes="fmp">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
    <!--
    XML stylesheet to format FMPXMLRESULT XML exported from Filemaker to FinalCutServer/Artbox
    Asset setMd XML (see example below).

    2007 Jim Mellor

    Note: FileMaker XML must contain the Asset ID field as the first value of
    each record (ie the first column of each row) for this template to work.

    <?xml version="1.0"?>
    <artbox>
    <request reqId="setMd" entityId="/asset/38215">
    <params>
    <mdValue fieldName="Asset ID" dataType="integer">38215</mdValue>
    <mdValue fieldName="Whatever" dataType="string">This is your data</mdValue>
    <mdValue fieldName="Client" dataType="string">Super Company</mdValue>
    <mdValue fieldName="Brand" dataType="string">Blue Wavey Gel</mdValue>
    <mdValue fieldName="Product" dataType="string">Housebase April Campaign</mdValue>
    <mdValue fieldName="Title" dataType="string">Etc etc</mdValue>
    </params>
    </request>
    </artbox>

    -->
    <!--
    Root match template
    -->
    <xsl:template match="fmp:FMPXMLRESULT">
    <FinalCutServer>
    <xsl:for-each select="fmp:RESULTSET/fmp:ROW">
    <xsl:call-template name="request">
    <xsl:with-param name="row" select="position()"/>
    </xsl:call-template>
    </xsl:for-each>
    </FinalCutServer>
    </xsl:template>
    <xsl:template name="getEntityId">
    <xsl:param name="row"/>
    <xsl:variable name="entId">
    <xsl:value-of select="normalize-space(/fmp:FMPXMLRESULT/fmp:RESULTSET/fmp:ROW[position()=$row]/fmp:COL[position()=1])"/>
    </xsl:variable>
    <xsl:variable name="prefix">
    <xsl:text>/asset/</xsl:text>
    </xsl:variable>
    <xsl:value-of select="concat($prefix, $entId)"/>
    </xsl:template>
    <xsl:template name="typeTranslator">
    <xsl:param name="fmpType"/>
    <xsl:choose>
    <xsl:when test="$fmpType = 'TEXT'">
    <xsl:text>string</xsl:text>
    </xsl:when>
    <xsl:when test="$fmpType = 'NUMBER'">
    <xsl:text>integer</xsl:text>
    </xsl:when>
    <xsl:when test="$fmpType = 'BOOLEAN'">
    <xsl:text>bool</xsl:text>
    </xsl:when>
    <xsl:when test="$fmpType = 'DATE'">
    <xsl:text>dateTime</xsl:text>
    </xsl:when>
    </xsl:choose>
    </xsl:template>
    <xsl:template name="request">
    <xsl:param name="row"/>
    <request>
    <xsl:attribute name="reqId">
    <xsl:text>setMd</xsl:text>
    </xsl:attribute>
    <xsl:attribute name="entityId">
    <xsl:call-template name="getEntityId">
    <xsl:with-param name="row" select="position()"/>
    </xsl:call-template>
    </xsl:attribute>
    <params>
    <xsl:for-each select="./fmp:COL">
    <xsl:call-template name="mdValue">
    <xsl:with-param name="col" select="position()"/>
    <xsl:with-param name="row" select="$row"/>
    </xsl:call-template>
    </xsl:for-each>
    </params>
    </request>
    </xsl:template>
    <xsl:template name="mdValue">
    <xsl:param name="col"/>
    <xsl:param name="row"/>
    <mdValue>
    <xsl:attribute name="fieldName">
    <xsl:value-of select="/fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD[$col]/@NAME"/>
    </xsl:attribute>
    <xsl:attribute name="dataType">
    <xsl:call-template name="typeTranslator">
    <xsl:with-param name="fmpType" select="/fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD[$col]/@TYPE"/>
    </xsl:call-template>
    </xsl:attribute>
    <xsl:value-of select="normalize-space(/fmp:FMPXMLRESULT/fmp:RESULTSET/fmp:ROW[position()=$row]/fmp:COL[position()=$col])"/>
    </mdValue>
    </xsl:template>
    </xsl:stylesheet>


    and fcsvr-fmp.xslt



    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.filemaker.com/fmpxmlresult" version="1.0">
    <!--
    XML stylesheet to format FinalCutServer/Artbox Asset getMdReply XML to Filemaker FMPXMLRESULT.

    2007 Jim Mellor

    Note: If importing a combined bunch of entities, the first will define the
    fields imported into Filemaker and their import order. For this reason it is
    important to ensure that your Final Cut Server or Artbox getMdReply/entity entries contains the
    same metadata fields in the same order.
    -->

    <!--
    Root match template
    -->
    <xsl:template match="/">
    <FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">
    <ERRORCODE>0</ERRORCODE>
    <PRODUCT BUILD="" NAME="" VERSION=""/>
    <DATABASE DATEFORMAT="M/d/yyyy" LAYOUT="" NAME="" RECORDS="{count(//)}" TIMEFORMAT="h:mm:ss a"/>
    <xsl:call-template name="METADATA"/>
    <xsl:call-template name="RESULTSET"/>
    </FMPXMLRESULT>
    </xsl:template>
    <xsl:template name="METADATA">
    <METADATA>
    <xsl:for-each select="/FinalCutServer/getMdReply/entity[1]/metadata/mdValue">
    <FIELD>
    <xsl:attribute name="EMPTYOK">YES</xsl:attribute>
    <xsl:attribute name="MAXREPEAT">1</xsl:attribute>
    <xsl:attribute name="NAME">
    <xsl:value-of select="@fieldName"/>
    </xsl:attribute>
    <xsl:attribute name="TYPE">
    <xsl:call-template name="typeTranslator">
    <xsl:with-param name="abType" select="@dataType"/>
    </xsl:call-template>
    </xsl:attribute>
    </FIELD>
    </xsl:for-each>
    </METADATA>
    </xsl:template>
    <xsl:template name="typeTranslator">
    <xsl:param name="abType"/>
    <xsl:choose>
    <xsl:when test="$abType = 'string'">
    <xsl:text>TEXT</xsl:text>
    </xsl:when>
    <xsl:when test="$abType = 'integer'">
    <xsl:text>NUMBER</xsl:text>
    </xsl:when>
    <xsl:when test="$abType = 'bool'">
    <xsl:text>TEXT</xsl:text>
    </xsl:when>
    <xsl:when test="$abType = 'dateTime'">
    <xsl:text>DATE</xsl:text>
    </xsl:when>
    <xsl:when test="$abType = 'coords'">
    <xsl:text>TEXT</xsl:text>
    </xsl:when>
    <xsl:when test="$abType = 'int64'">
    <xsl:text>NUMBER</xsl:text>
    </xsl:when>
    <xsl:when test="$abType = 'timecode'">
    <xsl:text>TEXT</xsl:text>
    </xsl:when>
    </xsl:choose>
    </xsl:template>
    <xsl:template name="RESULTSET">
    <RESULTSET>
    <xsl:attribute name="FOUND">
    <xsl:value-of select="count(/FinalCutServer/getMdReply/entity)"/>
    </xsl:attribute>
    <xsl:for-each select="/FinalCutServer/getMdReply/entity/*">
    <ROW>
    <xsl:attribute name="MODID">0</xsl:attribute>
    <xsl:attribute name="RECORDID">0</xsl:attribute>
    <xsl:for-each select="mdValue">
    <COL>
    <DATA>
    <xsl:value-of select="."/>
    </DATA>
    </COL>
    </xsl:for-each>
    </ROW>
    </xsl:for-each>
    </RESULTSET>
    </xsl:template>
    </xsl:stylesheet>
  • by Jamie Hodge,

    Jamie Hodge Jamie Hodge Nov 2, 2010 2:03 AM in response to Jim Mellor
    Level 1 (15 points)
    Nov 2, 2010 2:03 AM in response to Jim Mellor
    Thank you Jim for sharing. It's good to see actual solutions being posted. XSLT transforms are not for the faint of heart, but it's great to have a solution published. I did such an integration a few years back and ended up using the legacy FileMaker XML format because the newer of the two seemed like such a problem child.