在进行xquery转换时,遇到了我想删除元素的空属性的情况。
示例:
<product
name="{data($cBRequestType1/ns0:BCAmessage/ns0:BCAservice/ns0:BCAservice-data/ns0:request/ns0:VerificationEnquiryRequest/ns0:product/@name)}"
a="{data($cBRequestType1/ns0:BCAmessage/ns0:BCAservice/ns0:BCAservice-data/ns0:request/ns0:VerificationEnquiryRequest/ns0:product/@a)}"
b="{data($cBRequestType1/ns0:BCAmessage/ns0:BCAservice/ns0:BCAservice-data/ns0:request/ns0:VerificationEnquiryRequest/ns0:product/@b)}"
c="{data($cBRequestType1/ns0:BCAmessage/ns0:BCAservice/ns0:BCAservice-data/ns0:request/ns0:VerificationEnquiryRequest/ns0:product/@c)}"
/>
on testing将输出设为<Product name="abc" a="xyz" b="def" c=""/>
这里我想删除具有空值的属性,即c。 我尝试了很多东西,但无法解决它。 任何人都知道如何做到这一点?
答案 0 :(得分:2)
如果需要构造属性,请测试它是否为空字符串。我使用了计算元素构造函数和let
子句来实现readabilty,但是代码和你一样做了,添加了@c
的属性检查。
element Product {
let $product = $cBRequestType1/ns0:BCAmessage/ns0:BCAservice/ns0:BCAservice-data/ns0:request/ns0:VerificationEnquiryRequest/ns0:product
return
attribute name { $product/@name },
attribute a {$product/@a },
attribute b {$product/@b },
if ($product/@c != '') then attribute c {$product/@c } else ()
}
如果输入数据中不存在该产品,您最好只添加原始属性而不是构建它们:
element product {
let $product = $cBRequestType1/ns0:BCAmessage/ns0:BCAservice/ns0:BCAservice-data/ns0:request/ns0:VerificationEnquiryRequest/ns0:product
return $product/@name, $product/@a, $product/@b, $product/@c
}
答案 1 :(得分:1)
您还可以使用直接构造函数和计算构造函数的混合,有时这种语法感觉更自然。只要将计算出的属性构造函数(对于可选属性)作为直接元素构造函数中的第一个内容,就可以实现自己的要求。
例如:
<product mandatory="foo">
{
if($some-condition)then
attribute optional { "bar" }
else()
}
</product>
当$ some-condition为true()
时,会导致:
<product mandatory="foo" optional="bar">
</product>
当$ some-condition为false()
时,会导致:
<product mandatory="foo">
</product>
因此,对于您提供的示例,您可以这样做:
<product name="{data($cBRequestType1/ns0:BCAmessage/ns0:BCAservice/ns0:BCAservice-data/ns0:request/ns0:VerificationEnquiryRequest/ns0:product/@name)}"
a="{(data($cBRequestType1/ns0:BCAmessage/ns0:BCAservice/ns0:BCAservice-data/ns0:request/ns0:VerificationEnquiryRequest/ns0:product/@a)) }"
b="{(data($cBRequestType1/ns0:BCAmessage/ns0:BCAservice/ns0:BCAservice-data/ns0:request/ns0:VerificationEnquiryRequest/ns0:product/@b))}">
{
if(data($cBRequestType1/ns0:BCAmessage/ns0:BCAservice/ns0:BCAservice-data/ns0:request/ns0:VerificationEnquiryRequest/ns0:product/@c))then
attribute c {
data($cBRequestType1/ns0:BCAmessage/ns0:BCAservice/ns0:BCAservice-data/ns0:request/ns0:VerificationEnquiryRequest/ns0:product/@c)
}
else()
}
</product>
但是,在我看来,您正在将属性从源节点复制到目标节点,并且您真的只想从源中复制可用的特定属性。如果是这种情况,那么这样做要简单得多:
let $product := $cBRequestType1/ns0:BCAmessage/ns0:BCAservice/ns0:BCAservice-data/ns0:request/ns0:VerificationEnquiryRequest/ns0:product
return
<product>
{
$product/(@name | @a | @b | @c)
}
</product>
如果要复制所有可用属性,只需使用$product/@*
。