简体   繁体   中英

how to remove empty attribute from xquery

While doing the xquery transformation I came across the condition where in I want to remove the empty attribute of an element.

Example:

<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 got the output as <Product name="abc" a="xyz" b="def" c=""/>

Here I want to remove the attribute having null value ie c. I tried many things but couldnt resolve it. Anyone having any idea how to do it?

If you need to construct the attributes, test if it is not the empty string. I used computed element constructors and a let clause for readabilty, but the code is doing the same like you did, adding the attribute check for @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 ()
}

If the product does not exist in the input data, you'd better go for just adding the original attributes instead of constructing them:

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
}

You can also use a mix of direct constructors and computed constructors, sometimes this syntax feels more natural. As long as you place your computed attribute constructors (for your optional attributes) as the first thing inside your direct element constructor, you will achieve your requirement.

For example:

<product mandatory="foo">
{
    if($some-condition)then
        attribute optional { "bar" }
    else()
} 
</product>

When $some-condition is true() it would result in:

<product mandatory="foo" optional="bar">
</product>

and when $some-condition is false() it would result in:

<product mandatory="foo">
</product>

So for your supplied example, you could do this:

<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>

However, it seems to me that you are copying attributes from the source node to the destination node, and that you really just want to copy specific attributes from the source that are available. If that is the case, then it is much simpler to just do this:

let $product := $cBRequestType1/ns0:BCAmessage/ns0:BCAservice/ns0:BCAservice-data/ns0:request/ns0:VerificationEnquiryRequest/ns0:product
return
    <product>
    {
        $product/(@name | @a | @b | @c)
    }
    </product>

If you want to copy all available attributes, just use $product/@* .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM