西班牙
斯潘4
随着越来越多的基于XML的数据源和Web服务响应用户的XML流,我们中的许多人开始感觉到需要一种工具,允许以简单灵活的方式从XML中提取数据。和往常一样,我们的团队对这一需求反应非常迅速,这就是为什么FME 2009被授权函数-一种用于查询XML数据集合的语言。XML的XQuery类似于数据库的SQL。
在这里,我将举几个例子来说明如何使用XQuery,并展示它的强大功能和方便性。无论如何,我不是XQuery专家,我的示例也不会假装是语言文档或手册的替代品,我只想分享我对FME和XQuery这一新的强大组合的积极印象。我将给出元素和属性提取、FLWOR(代表for-LET-WHERE-ORDER BY-RETURN-类似于SQL中的SELECT-FROM-WHERE)查询、简单条件(IF-THEN-ELSE)和连接表达式的示例。
在继续查询之前,让我们先看看从XML中提取数据的老式方法(这里我们讨论的是一个任意的XML,其中我们没有通过xfMAP将XML元素映射到FME特性)。在FME 2008和之前,任何通过web服务(例如,作为HTTPFetcherresponse)到达的XML数据都必须使用StringSearcher进行搜索。所需的元素将被放入一个list属性中,然后必须对其进行索引和重命名。因此,对于每个元素,您至少需要三个变压器:
StringSearcher中的正则表达式可能非常复杂:
而且,也不是很可靠。例如,同一个元素的多次出现将很难跟踪。StringSearcher不区分不同的XML部分,因此它根本不是解析此类数据的好工具。
49.138000,-122.857000 200
项目点 加拿大,萨里,公元前7455 132号 加利福尼亚州 加拿大 公元前 萨里 7455 132 V3W -122.8566950,49.1378180,0 ...........
正如您可能注意到的
XQueryExtractor转换器的“参数”对话框(我主要使用这个)看起来相当可怕:
不过,这并不是那么糟糕——七个参数只指定在哪里查找数据以及如何查询数据,其余参数都有默认值。
还有一个XQUERY表达式窗口,我们可以在其中键入查询:
查询结果转到“中指定的属性”结果属性“参数。
(:Query#1:)声明命名空间x=“http://earth.google.com/kml/2.0”;/x:kml/x:Response/x:Placemark/x:address
请注意,笑脸(::)用于注释。
双斜杠“/”表示查询应该向下查看整个树,而不一定是在指定的级别,因此查询可以简单一些:
(:Query#2:)声明命名空间x=“http://earth.google.com/kml/2.0";
//x:地址
以上两个查询都将为我们提供原始XML的以下结果:
此XML中有另一个命名空间定义在
(: Query #3:)声明名称空间x="
http://earth.google.com/kml/2.0”;declare namespace y="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0";
/x:kml/x:Response/x:Placemark/y:AddressDetails/y:Country/y:CountryName
或者,如果不使用第二个名称空间上方的元素:
(:Query#4:)声明命名空间y=“urn:oasis:names:tc:ciq:xsdschema:xAL:2.0”;
//y:国家名称
以上两个问题都将给出以下结果:
例如,我们通常不需要XML标记,而是希望获得标记的内容。用string()函数扩展后修改的查询#1如下所示:
(:Query#5:)声明命名空间x=“http://earth.google.com/kml/2.0”;字符串(/x:kml/x:Response/x:Placemark/x:address)
加拿大,萨里,公元前7455 132号
(:查询#6:)声明名称空间x=“http://earth.google.com/kml/2.0”;substring-before (string (/ / x:坐标)、“,”)为了得到Y坐标,我们必须将内容转换成一个序列,并删除它的第一个和最后一个元素:
(:查询#7:)声明名称空间x=“http://earth.google.com/kml/2.0”;删除(删除(标记(字符串(/ / x:坐标),","),3),1)
可以找到一个很好的XQuery函数参考在这里.
前一节中的工作区使用了从谷歌接收的原始数据中的一小部分XML。如果我们对整个XML文件运行上面显示的其中一个查询会怎么样?(看到FLWOR。fmw workspace声明名称空间x=" "http://earth.google.com/kml/2.0";
数据(/ / x:地址)
7455 132 St, Surrey, BC, Canada|British Columbia V3W 1J8, Canada| Surrey, BC, Canada| Surrey, BC, Canada| Greater Vancouver Regional District, British Columbia, Canada|British Columbia, Canada| Canada| North America
(:查询#9:)声明名称空间x=“http://earth.google.com/kml/2.0”;声明名称空间y = " urn: oasis:名字:tc:出入境检验检疫局:xsdschema: xAL: 2.0”;对于$n in //x:Placemark let $maxAcc:= max(//y:AddressDetails/number(@Accuracy)),其中$n/ y:AddressDetails/number(@Accuracy) = $maxAcc返回数据($n/x:address)
加拿大,萨里,公元前7455 132号
(:Query#10:)声明命名空间x=“http://earth.google.com/kml/2.0”;声明名称空间y = " urn: oasis:名字:tc:出入境检验检疫局:xsdschema: xAL: 2.0”;对于//x:Placemark中的$n,其中$n//y:AddressDetails/number(@accurity)=3返回数据($n/x:address)结果是:
加拿大不列颠哥伦比亚省大温哥华地区
(:Query#11:)声明命名空间x=“http://earth.google.com/kml/2.0”;注意,我添加了外部< dml公司>标签,这样我们就得到了一个XML文档。这里的< dml公司>表示Dmitri的标记语言:-){//x:Placemark} 未知的位置 国家层面的 区域(州、省、州等 分区(县、市等)级 镇(市、村)级 邮政编码(邮编)级别 街道上 十字路口水平 地址水平 房屋(建筑名称、物业名称、购物中心等)层
(:Query#12:)声明命名空间x=“http://earth.google.com/kml/2.0”;声明名称空间y = " urn: oasis:名字:tc:出入境检验检疫局:xsdschema: xAL: 2.0”;对于$addr in//x:Placemark,$accr in//addressaccurity,其中$addr//@accurity=$accr/@accurity return concat(data($addr/x:address),“(accurity:,data($accr),”)
加拿大不列颠哥伦比亚省萨里市大街7455 132号(准确度:地址级别)*不列颠哥伦比亚省V3W 1J8号(准确度:邮政编码(邮政编码)级别)*加拿大不列颠哥伦比亚省V3W 4M7号(准确度:邮政编码(邮政编码)级别)*加拿大不列颠哥伦比亚省萨里市(准确度:邮政编码(邮政编码)级别)*加拿大不列颠哥伦比亚省萨里市(准确度:镇(市、村)级别)*大温哥华地区加拿大不列颠哥伦比亚特区(精度:分区(县、市等)级)*加拿大不列颠哥伦比亚省(精度:地区(州、省、州等)级)*加拿大(精度:国家级)*北美(精度:未知位置)
…加拿大不列颠哥伦比亚省 … 加利福尼亚州 加拿大 公元前
(:Query#13:)声明命名空间y=“urn:oasis:names:tc:ciq:xsdschema:xAL:2.0”;对于$pc in//y:AddressDetails返回if(not($pc//y:PostalCodeNumber))then(“n/a”)else(data($pc//y:PostalCodeNumber))
V3W*V3W 1J8*V3W 4M7*V3W*n/a*n/a*n/a*n/a*n/a*n/a*n/a
declare namespace x=“http://earth.google.com/kml/2.0”;//x:地点标记
这意味着transformer将从每个Placemark元素中创建一个单独的特性(在上一步之后,我们只有四个元素)。
注:谷歌给我们的地址(7455132 St,Surrey)并不完全是安全软件所在的大楼。亚搏在线我们真正的楼号是7445。最初我认为这是不好的,但后来我决定保持原样-就像警告说反向地理编码可能不太可靠-不要使用它来满足您的邮件需求。
我希望这个页面能够帮助您了解FME和XQuery的结合能力有多强大,并且您会发现它在您的数据转换中非常有用。
声明函数local:twillights($twl){{local:twillights(//civil)}{local:twillights(//nautical)}{local:twillights(//astrogical)}
08:30:58分 18点53分
xquery2html_kml.fmwt(:Query#14:)声明函数local:twillights($twl){{让$m:=数据(//month)返回if($m=“1”),然后是“一月”else if($m=“2”),然后是“二月”else if($m=“3”),然后是“三月”else if($m=“4”),然后是“四月”else if($m=“5”),然后是“五月”else if($m=“6”),然后是“六月”else if($m=“7”),然后是“七月”else if($m=“8”),然后是“八月”else if($m=“9”),然后是“九月”else if($m=“10”),然后“十月”else if($m=“11”)那么“十一月”else“十二月”},{data(//day)}
at{let$lat:=number(//latitude)返回if($lat<0),然后返回concat(abs($lat),“deg S”)else concat($lat,“deg N”)},{let$lng:=number(//longitude)返回if($lng<0),然后返回concat(abs($lng),“deg W”)else concat($lng,“deg”)}
时区:{data(//timezone)}({let$dst:=number(//dst)返回if($dst=1),然后返回“dst”else“”})
日出 | 日落 | |
---|---|---|
{数据(/ /日出)} | {数据(/ /日落)} | |
民事 | 08:30:58分 | 18点53分 |
{concat(大写(substring(名称($ twl[1]), 1, 1)),子串(名字($ twl [1]), 2))} | 数据($ {twl [1])} | 数据($ {twl [2])} |
{concat(大写(substring(名称($ twl[1]), 1, 1)),子串(名字($ twl [1]), 2))} | 数据($ {twl [1])} | 数据($ {twl [2])} |
日出 | 日落 | |
---|---|---|
{数据(/ /日出)} | {数据(/ /日落)} | |
暮色搏斗 | ||
早.... | 晚上 |
我调用了我的结果属性kml_描述_原始_文本.现在,如果我将输出发送到KML,并单击该点,我将得到以下带有HTML的placemark气球:
在FME 2010中,XQuery transformers得到了三个与FME相关的XQuery函数:FME:has属性(
这些函数确实可以简化许多与xml相关的任务。
我们已经看到了一个示例,展示了如何使用XQuery生成HTML代码(
参见上面的HTML创建和用户定义函数)。
这里,我将展示如何在XQuery中使用fme:get-attribute函数。
此示例工作区基于“
变压器使用统计例如,它扫描指定的路径,查找工作空间,读取它们的内容,并搜索transformer部分:
--准备包含表头的html(如果要使用此XQuery,请删除注释)
排名 | 变压器 | #变压器 | % |
---|---|---|---|
——添加行号(计数器){$i+1} | ——get transformer name {fme:get-attribute("list{", $i, "}._transformer_name"))} | ——获取使用{fme:get-attribute("list{", string($i), "}._number_of_transformer ")的变压器数量 | ——获取变压器使用的百分比从变压器的总数{fme:get-attribute(concat("list{", string($i), "}._percentage"))}——循环结束 |
输出是包含HTML代码的属性。
?2019安全亚搏在线软件公司|合法的