我是XSLT的新手,我正在尝试使用fmpxmlresult语法转换从Filemaker Pro生成的XML文件。 Filemaker通过以下方式输出RAW XML:
<?xml version="1.0" encoding="UTF-8"?>
<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">
<ERRORCODE>0</ERRORCODE>
<PRODUCT BUILD="02-13-2018" NAME="FileMaker" VERSION="ProAdvanced 16.0.5" />
<DATABASE DATEFORMAT="D/m/yyyy" LAYOUT="" NAME="fatture elettronica.fmp12" RECORDS="1" TIMEFORMAT="k:mm:ss " />
<METADATA>
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="data" TYPE="DATE" />
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="ID" TYPE="TEXT" />
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="righe::descrizione" TYPE="TEXT" />
<FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="righe::prezzo" TYPE="TEXT" />
</METADATA>
<RESULTSET FOUND="1">
<ROW MODID="1" RECORDID="1">
<COL>
<DATA>31/08/2018</DATA>
</COL>
<COL>
<DATA>1</DATA>
</COL>
<COL>
<DATA>patate</DATA>
<DATA>pomodori</DATA>
<DATA>uva</DATA>
</COL>
<COL>
<DATA>100</DATA>
<DATA>50</DATA>
<DATA>70</DATA>
</COL>
</ROW>
</RESULTSET>
</FMPXMLRESULT>
在我的XSLT中,使用
选择字段<xsl:value-of select="fmp:COL[1]/fmp:DATA"/>
它可以工作,但是有点麻烦,因为我有一个包含很多字段的XML文件,而且很容易按数字查找错误的字段。 有没有一种方法可以使用元数据部分中列出的字段名称来选择字段? 我尝试搜索,但我什至无法想象要寻找的正确关键字。 谢谢
答案 0 :(得分:1)
您可以定义一个键来保存字段名称,并使用count函数从中获取名称。
这样的事情。
<!-- Define a key to get the first field and all fields that follow it by the field name -->
<xsl:key name="K" match="/fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD" use="@NAME" />
<xsl:key name="K" match="/fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD" use="following-sibling::fmp:FIELD/@NAME" />
<!-- Shortform to get a value for an attribute -->
<MyField SomeAttr="{fmp:COL[count(key('K', 'SomeAttr'))]}"/>
<!-- Format for getting a value for an element -->
<MyField>
<xsl:value-of select="fmp:COL[count(key('K', 'MyField'))]/fmp:DATA" />
</MyField>
此方法还具有以下优点:如果您在FileMaker中更改字段导出顺序,则XSLT将保持不变。如果您在FileMaker中更改字段名称,则只需更改XSLT中获取该字段的一条语句即可。
答案 1 :(得分:0)
在纯XSLT / XPath 1中,很难找到一个紧凑的表达式,例如要选择相应的namespace B {
enum bar {
HELLO,
WORLD
};
}
typedef ::B::bar my_type;
namespace A {
namespace B {
template<my_type= ::B::WORLD> class foo {
};
}
}
int main(int argc, char* argv[])
{
A::B::foo<> myFoo;
}
具有FIELD
属性值NAME
的列,像ID
这样的复杂选择:
<xsl:value-of select="fmp:COL[count($fields[@NAME = 'ID']/preceding-sibling::fmp:FIELD) + 1]/fmp:DATA"/>
https://xsltfiddle.liberty-development.net/94hvTzA/2
在XSLT 2或3中,您可以定义一个函数,该函数基于<?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"
exclude-result-prefixes="fmp"
version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="//fmp:ROW"/>
</xsl:template>
<xsl:variable name="fields" select="//fmp:FIELD"/>
<xsl:template match="fmp:ROW">
<xsl:value-of select="fmp:COL[count($fields[@NAME = 'ID']/preceding-sibling::fmp:FIELD) + 1]/fmp:DATA"/>
</xsl:template>
</xsl:stylesheet>
属性值返回想要的FIELD
的索引,并具有紧凑的NAME
表达式:
<xsl:value-of select="COL[mf:col-pos('ID')]/DATA"/>
答案 2 :(得分:0)
我以这种方式解决了
<xsl:variable name="mdf" select="/fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD" />
<xsl:variable name="ID" select="count($mdf[following-sibling::fmp:FIELD/@NAME = 'ID']) + 1" />
然后我将变量称为:
<xsl:value-of select="fmp:COL[$ID]/fmp:DATA"/>