简体   繁体   English

如何在 XQuery 中使用条件?

[英]How to use condition in XQuery?

I have sample xml data with address.我有带有地址的示例 xml 数据。 It works well but there's one problem.它运作良好,但有一个问题。 I use "/" to concatenate house number and flat number but if there's no flat number I receive something like that: 1 /.我使用“/”来连接门牌号码和单位号码,但如果没有单位号码,我会收到类似的信息:1 /。

Here's my example:这是我的例子:

declare @xml as xml = '<root>
                    <Row>
                            <proceeding>
                                    <signatures>V GU 86/18</signatures>
                                    <signatures>V GUp 9/19</signatures>
                                    <signatures>V GUp 8/19</signatures>
                            </proceeding>
                            <entity>
                                    <info>
                                            <cleaned_name>Kate Smith</cleaned_name>
                                    </info>
                                    <address>
                                            <town>London </town>
                                            <house_number>1 </house_number>
                                            <flat_number>1</flat_number>
                                            <street>Downing Street</street>
                                            <zip_code>00-001</zip_code>
                                    </address>
                                    <address>
                                            <town>Yorkshire </town>
                                            <house_number>1 </house_number>
                                            <flat_number>1</flat_number>
                                            <street>Morning Street</street>
                                            <zip_code>00-999</zip_code>
                                    </address>
                            </entity>
                            <entity>
                                    <info>
                                            <cleaned_name>John Smith</cleaned_name>
                                    </info>
                                    <address>
                                            <town>Washington </town>
                                            <house_number>1</house_number>
                                            <flat_number>1</flat_number>
                                            <street>Pennsylvania Avenue</street>
                                            <zip_code>00-001</zip_code>
                                    </address>
                                    <address>
                                            <town>Washington </town>
                                            <house_number>1</house_number>
                                            <flat_number></flat_number>
                                            <street>Pennsylvania Avenue</street>
                                            <zip_code>00-001</zip_code>
                                    </address>
                            </entity>
                    </Row>
            </root>'


            select 
             isnull(STUFF(a.x.query('for $s in  entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu' 
            ,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
            ,isnull(STUFF(a.x.query('for $s in entity/address
                        return
                        <x>{concat(", ",($s/zip_code/text())[1]," "
                                       ,($s/town/text())[1]," "
                                       ,($s/street/text())[1]," "
                                       ,($s/house_number/text())[1],"/"
                                       ,($s/flat_number/text())[1]
                                   )}</x>')
               .query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'')  
from @xml.nodes('/root/Row') as a(x);

This is what I get:这就是我得到的: 在此处输入图片说明

And that's my desired outcome:这就是我想要的结果: xml

Here's what I've tried so far:这是我迄今为止尝试过的:

declare @v varchar(20)='house_number'

            select 
            isnull(STUFF(a.x.query('for $s in  entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu' 
            ,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
            ,isnull(STUFF(a.x.query('if (sql:variable("@v")="") then for $s in entity/address
            return
            <x>{concat(", ",($s/zip_code/text())[1]," "
            ,($s/town/text())[1]," "
            ,($s/street/text())[1]," "
            ,($s/house_number/text())[1]
            )}</x>
            else                     
            <x>{concat(", ",($s/zip_code/text())[1]," "
            ,($s/town/text())[1]," "
            ,($s/street/text())[1]," "
            ,($s/house_number/text())[1],"/"
            ,($s/flat_number/text())[1]
            )}</x>          
            ')                                              
            .query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'') 
            from @xml.nodes('/root/Row') as a(x);

I receive the following error: XQuery [query()]: The variable '$s' was not found in the scope in which it was referenced.我收到以下错误:XQuery [query()]:在引用它的范围内找不到变量“$s”。 I'm wondering if I can achieve my goal in that way.我想知道我是否可以通过这种方式实现我的目标。

I'm not quite sure what problem the other answers are solving, but for the question as described in the title, you can replace我不太确定其他答案正在解决什么问题,但是对于标题中描述的问题,您可以替换

($s/house_number/text())[1],"/",($s/flat_number/text())[1]

in the concat params with在 concat 参数中

string-join((($s/house_number/text())[1], ($s/flat_number/text())[1]), '/')

which will insert the "/" only if both house-number and flat-number exist.仅当门牌号和公寓号都存在时才会插入“/”。

I can't see why the [1] subscripts are needed (perhaps to defeat static type-checking?) but I've left them in.我不明白为什么需要[1]下标(也许是为了打败静态类型检查?)但我已经把它们留在了。

I've done it other way and it works.我以其他方式完成了它并且它有效。

            select 
             isnull(STUFF(a.x.query('for $s in  entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu' 
            ,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
            ,isnull(STUFF(a.x.query('for $s in entity/address
                        return

                                                    if ($s/flat_number="")
                                                    then
                        <x>{concat(", ",($s/zip_code/text())[1]," "
                                       ,($s/town/text())[1]," "
                                       ,($s/street/text())[1]," "
                                       ,($s/house_number/text())[1]
                                   )}</x>

                                                    else
                                                    <x>{concat(", ",($s/zip_code/text())[1]," "
                                                                            ,($s/town/text())[1]," "
                                                                            ,($s/street/text())[1]," "
                                                                            ,($s/house_number/text())[1],"/"
                                                                            ,($s/flat_number/text())[1]
                                                                            )}</x>       
                                                    ')
               .query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'')  
from @xml.nodes('/root/Row') as a(x);

Well, in this case your last question's title (which I've changed in the meanwhile) "How to use LET" might have a revival :-)好吧,在这种情况下,您最后一个问题的标题(同时我已更改)“如何使用 LET”可能会复活:-)

Try this:尝试这个:

select 
    isnull(STUFF(a.x.query('for $s in  entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu' 
,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
,isnull(STUFF(a.x.query('for $s in entity/address
            let $houseFlat:=if($s/flat_number/text()) 
                            then concat(($s/house_number/text())[1],"/",($s/flat_number/text())[1])
                            else string(($s/house_number/text())[1])
            return
            <x>{concat(", ",($s/zip_code/text())[1]," "
                            ,($s/town/text())[1]," "
                            ,($s/street/text())[1]," "
                            ,$houseFlat
                        )}</x>')
    .query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'')  
from @xml.nodes('/root/Row') as a(x);

But - at least in this case - distinct-values() will not help.但是 - 至少在这种情况下 - distinct-values()无济于事。 The both addresses are not identical due to 1 and 1/1 in the house and street number ...由于房屋和街道号码中的11/1 ,这两个地址并不相同......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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