Xquery — Выбор значения из XML с помощью XMLTable

#xml #db2 #xquery

#xml #db2 #xquery

Вопрос:

Я хочу использовать XQuery для отображения значения, если FrequencyCdvalue="01" и city type="first" в следующем XML.

Не могли бы вы, пожалуйста, помочь мне здесь

 <Envelope>
<Arrangement>
<FrequencyCd value="01">first first</FrequencyCd> 
<FrequencyCd value="02">first second</FrequencyCd> 
<contactinfo> <Address>
<street>234 Rolling Lane</street> 
<city type="first">Rockport</city> 
</Address>
<email>love2fish@finmail.com</email> 
</contactinfo>
</Arrangement>
<Arrangement>
<FrequencyCd value="03">second first</FrequencyCd> 
<FrequencyCd value="04">second second</FrequencyCd> 
<contactinfo>
<Address>
<street>234 Straight Lane</street> 
<city type="first">Crackport</city> 
</Address>
<email>hate2fish@finmail.com</email> 
</contactinfo>
</Arrangement>
</Envelope>
  

Комментарии:

1. Какое значение вы пытаетесь отобразить? xpath /Envelope/Arrangement[FrequencyCd/@value='01' and contactinfo/Address/city/@type='first'] должен помочь вам начать.

2. Большое спасибо разработчикам — я могу получить XPATH для этого, но когда я пытаюсь поместить это в Xquery (на самом деле нам нужен запрос DB2) и отобразить значения для частотного кода 01 и city type = first

Ответ №1:

Этот подход удаляет больше строк внутри, но позволяет реализовать составные критерии фильтрации (условия для FrequencyCd и City) в виде простого предложения WHERE в SQL-представлении измельченных XML-данных (выходных данных функции XMLTABLE).

 with origxml(xdoc) AS (VALUES XMLPARSE( DOCUMENT 
    '<Envelope>
    <Arrangement>
    <FrequencyCd value="01">first first</FrequencyCd> 
    <FrequencyCd value="02">first second</FrequencyCd> 
    <contactinfo> <Address>
    <street>234 Rolling Lane</street> 
    <city type="first">Rockport</city> 
    </Address>
    <email>love2fish@finmail.com</email> 
    </contactinfo>
    </Arrangement>
    <Arrangement>
    <FrequencyCd value="03">second first</FrequencyCd> 
    <FrequencyCd value="04">second second</FrequencyCd> 
    <contactinfo>
    <Address>
    <street>234 Straight Lane</street> 
    <city type="first">Crackport</city> 
    </Address>
    <email>hate2fish@finmail.com</email> 
    </contactinfo>
    </Arrangement>
    </Envelope>'
    )
)
SELECT filteredxml.FrequencyCd, filteredxml.City FROM origxml,
XMLTABLE ('$d/Envelope/Arrangement' PASSING origxml.xdoc AS "d"
                COLUMNS
                FrequencyCd     VARCHAR(20) PATH    'FrequencyCd[@value="01"]/text()',
                City            VARCHAR(30) PATH    'contactinfo/Address/city[@type="first"]/text()'
            ) as filteredxml
WHERE filteredxml.FrequencyCd IS NOT NULL
AND filteredxml.City IS NOT NULL
;                   
  

Комментарии:

1. Большое спасибо, Фред — Это сработало — Также у меня есть еще одно требование, в котором я должен использовать // (т. е. Где бы оно ни существовало в XML), т. е. использовать // Arrangement / FrequencyCd [@value =»01″], но когда я пытаюсь это сделать, я получаю ошибку.

2. Большое спасибо, Фред — Это сработало — Также у меня есть еще одно требование, в котором я должен использовать // (т. е. Где бы оно ни существовало в XML), т. е. использовать // Arrangement / FrequencyCd [@value =»01″], но когда я пытаюсь это сделать, я получаю ошибку. — Я также пытался удалить ‘$ d / Envelope / Arrangement’ — Спасибо за вашу помощь В ВЫБОРЕ filteredxml. FrequencyCd, filteredxml. Город ИЗ testxml, XMLTABLE (‘$d/Envelope/Arrangement’, ПЕРЕДАЮЩИЙ testxml.contact В ВИДЕ «d» СТОЛБЦОВ FrequencyCd VARCHAR(20) PATH ‘//FrequencyCd[@value=»02″]/text()’, ПУТЬ к ПЕРЕМЕННОЙ City(30) PATH ‘//contactinfo/Address/city[@type=»first»]/text()’) как filteredxml

3. Это образец XML, и мое фактическое требование — работать с большим xml-файлом — я хочу знать, есть ли способ, которым я могу ссылаться на разные пути в одном и том же Xquery, например //ABC / DEF / GHI и ?? MNO / PQR / STU

4. XMLTABLE должен знать, что представляет собой ваше выражение, создающее строку, чтобы работать. Если ваш XML-документ организован не так, чтобы он имел смысл в виде таблицы, вы не сможете получить нужные результаты за один вызов XMLTABLE. В таких ситуациях вы могли бы объединить несколько выражений XMLTABLE вместе или запустить документ через XSLTRANSFORM, чтобы радикально реорганизовать его, чтобы заставить его работать с одним выражением XMLTABLE.