Oracle XMLTABLE 和 XPATH

问题描述

我对 Xpath 有点迷茫,我正在尝试从 XML 获取属性,我目前正在使用:

XMLTABLE('/attrs/attr[@name="ImagesWEB"]/string'
    PASSING XMLTYPE(XML)
    COLUMNS IMAGESWEB VARCHAR2(100) PATH '.'
)

但我需要获得一个属性名称Image2 的其他值,所以我做了另一个 XMLTABLE,但我想这不是正确的方法,我必须使用 XMLTABLE('/attrs /attr'... 有两列,但不知道如何从 XPATH 中获得两列(XML 数据中可能缺少 Image2)?

这是一个 XML 示例(用于我产品的 CLOB):

<attrs>
    <attr multiple="true" name="Image2">
        <string>IMG2.PNG</string>
        <string>IMG3.PNG</string>
        <string>IMG4</string>
    </attr>
    <attr multiple="true" name="ImagesWEB">
        <string>IMG.PNG</string>
    </attr>
    <attr name="ShortLink">
        <string>/PRODUCT.html</string>
    </attr>
    <attr name="TITRE">
        <string>TITLE</string>
    </attr>
    <attr name="name">
        <string>PRODUCT</string>
    </attr>
</attrs>

Thansk!

解决方法

您可以更改主 XPath 以获取 attrs,然后在每个 columns 子句的 Xpath 中过滤您想要的:

XMLTABLE('/attrs'
    PASSING XMLTYPE(XML)
    COLUMNS
      IMAGESWEB VARCHAR2(100) PATH 'attr[@name="ImagesWEB"]/string',IMAGE2 VARCHAR2(100) PATH 'attr[@name="Image2"]/string'
)

db<>fiddle 带有一些虚构的数据。


但是如果我有两个值(可能会发生)怎么办?

如果你可以在一个属性下有多个 string 节点,那么你可以从一个 XMLTable 调用中获得两个 attr 节点,然后再有两个 - 每个属性一个 - 来获取字符串:

SELECT t.id,x2.imagesweb,x3.image2
FROM your_table t
CROSS APPLY
XMLTABLE('/attrs'
    PASSING XMLTYPE(t.XML)
    COLUMNS
      IMAGESWEB XMLTYPE PATH 'attr[@name="ImagesWEB"]',IMAGE2 XMLTYPE PATH 'attr[@name="Image2"]'
) x1
OUTER APPLY
XMLTABLE('/attr/string'
    PASSING x1.imagesweb
    COLUMNS
      IMAGESWEB VARCHAR2(100) PATH '.'
) x2
OUTER APPLY
XMLTABLE('/attr/string'
    PASSING x1.image2
    COLUMNS
      IMAGE2 VARCHAR2(100) PATH '.'
) x3
ID IMAGESWEB  IMAGE2
-- ---------  ----------
 1 ABC        DEF
 2 ABC
 3            DEF
 3            DEF2
 4 IMG.PNG    IMG2.PNG
 4 IMG.PNG    IMG3.PNG
 4 IMG.PNG    IMG4

db<>fiddle 混合了虚构数据和样本数据。

这使用交叉应用和外部应用(因为一个或另一个属性可能不存在),它们可用 from Oracle 12c (12.1.0.1)