我希望通过提及Filemaker我不会失去任何人.我试图将它的XML导出转换为SSIS可用的东西. FM的原生XML导出在同一XML文件的不同部分中具有字段名称和数据.这列出了我需要它做什么,我目前做了什么,以及底部的原始FM导出以供参考.我今天早上还没有看过XML翻译,所以请耐心等待:D.我可以根据需要发布更多信息.
<!-- What we actually want example --> <?xml version="1.0" encoding="UTF-8"?> <PRODUCTRECS> <PRODUCT> <name>Dr. Zim</name> <address>1234 Internet Way</address> <city/><state/><zip/> </PRODUCT> ... </PRODUCTRECS>
有没有办法让XSLt读取顶部的字段名称,并在翻译时将字段名称放在实际数据周围?目前,我只是选择IF语句这样的位置(这样可行,但非常依赖和混乱):
<!-- Current nightmare code,check for each individually and print it out --> <xsl:template match="fmp:FMPXMLRESULT"> <PRODUCTRECS> <xsl:for-each select="fmp:RESULTSET/fmp:ROW"> <PRODUCT> <xsl:for-each select="fmp:COL"> <xsl:if test="position()=1"> <name><xsl:value-of select="fmp:DATA"/></name> </xsl:if> ... </xsl:for-each> </PRODUCT> </xsl:for-each> </PRODUCTRECS> </xsl:template>
<?xml version="1.0" encoding="UTF-8" ?> <FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult"> <ERRORCODE>0</ERRORCODE> <PRODUCT BUILD="01-01-2009" NAME="FileMaker Pro" VERSION="10.0v3"/> <DATABASE DATEFORMAT="M/d/yyyy" LAYOUT="" NAME="filename.fp7" RECORDS="10" TIMEFORMAT="h:mm:ss a"/> <MetaDATA> <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="name" TYPE="TEXT"/> <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="address" TYPE="TEXT"/> <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="city" TYPE="TEXT"/> <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="state" TYPE="TEXT"/> <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="zip" TYPE="TEXT"/> </MetaDATA> <RESULTSET FOUND="10"> <ROW MODID="0" RECORDID="1"> <COL><DATA>Dr. Zim</DATA></COL> <COL><DATA>1234 Internet Way</DATA></COL> <COL><DATA></DATA></COL> <COL><DATA></DATA></COL> <COL><DATA></DATA></COL> ... </ROW> ... </RESULTSET> </FMPXMLRESULT>
期待着那里的大师XSLTers. :)我的另一个问题是当原始文件在XML中存储为文本(00009.99000000)时,如何格式化数字价格为9.99美元的货币,但我可以处理这个.
解决这个问题的一个优雅方法是:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fmp="http://www.filemaker.com/fmpxmlresult" exclude-result-prefixes="fmp" > <!-- the key indexes the MetaDATA fields by their position --> <xsl:key name="kMetaData" match="fmp:MetaDATA/fmp:FIELD" use="count(preceding-sibling::fmp:FIELD) + 1" /> <!-- separate templates increase readability --> <xsl:template match="/fmp:FMPXMLRESULT"> <PRODUCTRECS> <xsl:apply-templates select="fmp:RESULTSET/fmp:ROW" /> </PRODUCTRECS> </xsl:template> <xsl:template match="fmp:ROW"> <PRODUCT> <xsl:apply-templates select="fmp:COL" /> </PRODUCT> </xsl:template> <xsl:template match="fmp:COL"> <!-- column name lookup is high-speed because of the key --> <xsl:element name="{string(key('kMetaData',position())/@NAME)}"> <xsl:value-of select="fmp:DATA" /> </xsl:element> </xsl:template> </xsl:stylesheet>
我系统上的哪些输出:
<PRODUCTRECS> <PRODUCT> <name>Dr. Zim</name> <address>1234 Internet Way</address> <city></city> <state></state> <zip></zip> </PRODUCT> </PRODUCTRECS>
但是,请注意,XML元素名称受制于比FileMaker列名更严格的规则.如果您的列名违反这些规则,上述内容将崩溃并刻录.
样式表的显着特征是:
> an< xsl:key>为了快速查找节点 – 对于较大的输入,这应该变得明显
> exclude-result-prefixes以防止在结果中声明fmp命名空间
>< xsl:element>使用动态名称创建元素
>使用prevIoUs-sibling XPath轴作为确定节点位置的方法(因为position()函数在< xsl:key>中不起作用
来吧,询问是否有任何不清楚的地方.
您的其他问题(数字格式)在这里有一个答案:XSL: Formatting numbers,excluding trailing zeroes.