0

在进行 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)}"
/>

在测试中得到的输出为<Product name="abc" a="xyz" b="def" c=""/>

在这里,我想删除具有空值的属性,即 c。我尝试了很多事情,但无法解决它。有人知道怎么做吗?

4

2 回答 2

2

如果需要构造属性,请测试它是否不是空字符串。我使用了计算元素构造函数和一个let子句来提高可读性,但是代码和你做的一样,为@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
}
于 2014-02-10T10:59:57.483 回答
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/@*.

于 2014-02-10T11:49:10.103 回答