使用xquery从xmltable获取所有属性

时间:2015-05-27 11:02:41

标签: xml oracle xquery

我有一个xml表,其中每个项目都有很多属性

例如,

DIG_POINT LowValue="2" StatusText1="LIG 21" StatusText2="LIG 22" StatusText3="LIG 23"

我见过的所有例子总是要引用列名

 SELECT xmlkey , x.*
     FROM xmlimport t,
          XMLTABLE ('/SRDBSW/DIG_POINT[@LowValue="2"]' PASSING t.XMLDATA COLUMNS StatusText1 VARCHAR2(30) PATH '@StatusText1') x
    WHERE xmlkey = 'TEST';

我的问题是可以动态添加属性名称。

有没有办法得到类似" select * from ....",哪里可以从每个项目中获取所有属性?

1 个答案:

答案 0 :(得分:3)

您可以使用XPath提取属性,并将每个属性转换为虚拟元素中的名称/值对:

SELECT t.xmlkey, x.*
FROM xmlimport t
CROSS JOIN XMLTABLE ('for $i in /SRDBSW/DIG_POINT[@LowValue="2"], $j in $i/@*
  return element tmp { attribute name {local-name($j)}, attribute value {$j} }'
  PASSING t.XMLDATA
  COLUMNS
    attr_name VARCHAR2(30) PATH '/tmp/@name',
    attr_value VARCHAR2(30) PATH '/tmp/@value'
) x
WHERE t.xmlkey = 'TEST';

XMLK ATTR_NAME                      ATTR_VALUE                   
---- ------------------------------ ------------------------------
TEST LowValue                       2                             
TEST StatusText1                    LIG 21                        
TEST StatusText2                    LIG 22                        
TEST StatusText3                    LIG 23                        

for $i in ...获取所有匹配的节点,正如您已经在做的那样;然后在for $j in $i/@*内获取该节点的所有属性。 element构造一个新节点,attribute子句将属性名称(从local-name())和实际属性值转换为该虚拟元素中的单独命名属性。然后path可以引用虚拟元素中的已知属性名称。

您实际上并不需要$i$j,它只会更清楚地显示正在发生的事情;如果您愿意,可以使用这样的XPath:

'for $i in /SRDBSW/DIG_POINT[@LowValue="2"]/@*
  return element tmp { attribute name {local-name($i)}, attribute value {$i} }'

甚至更简单,将local-name()查找移至path

SELECT t.xmlkey, x.*
FROM xmlimport t
CROSS JOIN XMLTABLE ('/SRDBSW/DIG_POINT[@LowValue="2"]/@*'
  PASSING t.XMLDATA
  COLUMNS
    attr_name VARCHAR2(30) PATH 'local-name(.)',
    attr_value VARCHAR2(30) PATH '.'
) x
WHERE t.xmlkey = 'TEST';

XMLK ATTR_NAME                      ATTR_VALUE                   
---- ------------------------------ ------------------------------
TEST LowValue                       2                             
TEST StatusText1                    LIG 21                        
TEST StatusText2                    LIG 22                        
TEST StatusText3                    LIG 23