首页 > 代码库 > XQuery元素构造,你知道多少?
XQuery元素构造,你知道多少?
今天遇到一个问题,对于下面这样一个xml串
<opDetail> <recordInfo> <fieldInfo> <fieldChName>告警流水号</fieldChName> <fieldEnName>alarmId</fieldEnName> <fieldContent>GJ_2816071613_352385154_2970760107_588354443</fieldContent> </fieldInfo> <fieldInfo> <fieldChName>告警ID</fieldChName> <fieldEnName>alarmStaId</fieldEnName> <fieldContent>2014070200101</fieldContent> </fieldInfo> </recordInfo> </opDetail>
如何转换成下面这种形式:
<opDetail> <recordInfo> <alarmId>GJ_2816071613_352385154_2970760107_588354443</alarmId> <alarmStaId>2014070200101</alarmStaId> </recordInfo> </opDetail>
根据之前在项目中配置各种解析脚本的经验,我的直觉告诉我通过xquery脚本,是可以实现这么一个转换过程,而且,之前在看《Xquery权威指南》一书时,曾看到类似的例子,于是我翻开《xquery权威指南》,根据目录提示,很快我就找到了解决办法,很简单,就是使用xquery构造元素。
使用xquery构造元素,有两种方式:直接元素构造(Direct element Construction)和计算构造(Computed Construction),下面来分别介绍:
- 直接元素构造
这种构造方式比较简单,比较容易理解。根据书中的描述“直接构造器,使用类似XML语法,用于创建名称固定的元素和属性。”当初看这句话,并没有给予太多关注,“使用类似XML语法”我感觉这是废话,而后面“用于创建名称固定的元素和属性”这句话则直接被我忽视了。而在解决上面的问题时,我才意识到这句话的重要性。作者的意思是,直接元素构造,适合使用与节点名称和属性名称已知的元素构造,而在我们遇到的问题中,节点的名称是未知的,因此不能使用直接元素构造的方式进行。说到现在,可能大家还不知道直接元素构造是怎么一回事,举两个栗子吧。
<opDetail> <recordInfo> { for $a in //fieldInfo return <name>{$a/fieldEnName/text()}</name> } </recordInfo> </opDetail>
在stylus-studio中针对问题中的xml串运行上面的脚本,得到如下结果:
<opDetail><recordInfo><name>alarmId</name><name>alarmStaId</name></recordInfo></opDetail>
可以看到在这里,节点opDetail,recordInfo以及name的名称都是固定的。
再比如
<opDetail> <recordInfo> { for $a in //fieldInfo return <name fieldChName="{$a/fieldChName/text()}">{$a/fieldEnName/text()}</name> } </recordInfo> </opDetail>
在stylus-studio中针对问题中的xml串运行上面的脚本,得到如下结果:
<opDetail><recordInfo><name fieldChName="告警流水号">alarmId</name><name fieldChName="告警ID">alarmStaId</name></recordInfo></opDetail>
同理,这里的属性名称fieldChName也是固定的。
- 计算构造
和直接元素构造不同,书中对计算构造器的描述是“允许在查询中动态生成名称。”
计算元素构造器,使用关键字element,后面跟着名称和内容。其中名称可以是字符串,也可以是用大括号括起来的名称表达式,而内容则必须是名称表达式。
语法如下:element 名称/名称表达式 内容表达式
最简单的构造方式,和上面的直接元素构造方法没什么差别,将节点的名称固定:
element html { element h1 { "This is a Test"} }
运行之后,返回的结果是
<html><h1>This is a Test</h1></html>
如果针对问题中的xml串,执行下面的语句
element opDetail { for $a in //fieldInfo return element {$a/fieldEnName/text()} {$a/fieldContent/text()} }
返回的结果是
<opDetail><alarmId>GJ_2816071613_352385154_2970760107_588354443</alarmId><alarmStaId>2014070200101</alarmStaId></opDetail>
此外,还可以这样,节点名称使用固定字符串+运算结果的方式进行,同样对问题中的xml文,执行下面的语句:
element opDetail { for $a in //fieldInfo return element {concat("ele",$a/fieldEnName/text())} {$a/fieldContent/text()} }
返回的结果是
<opDetail><elealarmId>GJ_2816071613_352385154_2970760107_588354443</elealarmId><elealarmStaId>2014070200101</elealarmStaId></opDetail>
更多的栗子就不多介绍了,翻开《xquery权威指南》第五章,你可以找到很多栗子。
总的说来,xquery元素构造,分为直接构造和计算构造,其中直接元素构造适用于节点/属性名称不变的情况,而计算构造适用于节点/属性名称可变的情况。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。