oracle xmltable获取子节点

时间:2015-05-29 10:42:32

标签: oracle xquery xmltable

<SRDBSW xmlns:xdb="http://xmlns.oracle.com/xdb" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Id="String"  ShortIds="Y" >
<OBJ_DF IdView="RW" ObjLevel="Element" Nature="" ObjectType="" ShortDescription="" ShortDescriptionCore="" LogicalShortDescription="" LongDescription="Reaction Wheel" LongDescriptionCore="" LogicalLongDescription="" Mnemonic="" IsDefined="Y" ModelType="" SerialNumber="" ProductTreeId="" CategoryFlag="7" OwnerFlag="7" InputVersion="" InputType="" InputReference="" >
   <TC_STR_DF IdView="TCSTABCDE" IsDirect="Y" CategoryFlag="0" OwnerFlag="0" ShortDescription="TC Packet Header Structure" ShortDescriptionCore="TC Packet Header Structure" LongDescription="Item: TC Structure" Mnemonic="TC Structure" Type="TC_STR" >
        <TC_STR_COMP_LIST>
            <TC_STR_COMP CompOrder="3" ComponentType="Editable parameter" CompId="HABCA" EngValue="3" TakeValue="From occurrence" MonParRef="MBCDA" Mandatory="Yes" />
        </TC_STR_COMP_LIST>
    </TC_STR_DF>
</OBJ_DF>

我在Oracle表的xmltable中有这部分XML(这只是一个示例,我的XML已满了这些部分):

    <SCOS_TM_DF IdView="1111" IsDirect="Y" CategoryFlag="0" OwnerFlag="0" ShortDescription="TC Packet Header Structure" ShortDescriptionCore="TC Packet Header Structure" LongDescription="Item: SCOS TM Packet" Mnemonic="SCOS TM Packet" Type="SCOS_TM" TpcfName="My TM packet" InterpretFlag="Both" DefOffsetTime="66" >
        <TM_STR_COMP_LIST>
            <TM_STR_COMP ComponentType="Single structure" CompId="TMSTABCDE" CompBytePos="0" CompBitPos="0" TimeOffset="0" SelectorParRef="MABCA" SelRawValue="0" />
        </TM_STR_COMP_LIST>
    </SCOS_TM_DF>

我需要找到所有ComponentType="Single structure",但也需要获得“父亲”SCOS_TM_DF IdView="1111"

到目前为止,我正在处理此查询,但无法获取idview:

SELECT x.* 
FROM xmlimport t 
CROSS JOIN XMLTABLE ('/SRDBSW/OBJ_DF/TC_STR_DF/TC_STR_COMP_LIST/TC_STR_COMP/@*' 
          PASSING t.XMLDATA   
          COLUMNS 
            IdView VARCHAR2(30) PATH '/../../../@IdView', 
          CompId     VARCHAR2(30) PATH '@CompId', 
          attr_name      VARCHAR2(30) PATH 'local-name(.)', 
          attr_value     VARCHAR2(90) PATH '.' ) x  
          WHERE t.xmlkey = 'SRDB-XML-sample-1.xml';

2 个答案:

答案 0 :(得分:1)

您还可以在XPath中构建自己的元素,该元素基于父节点创建属性:

SELECT x.*
FROM xmlimport t
CROSS JOIN XMLTABLE ('for $i in //*[@ComponentType = ''Single structure'']
    return element {$i/name()} { attribute CompId {$i/@CompId},
      attribute IdView {$i/../../@IdView},
      $i }'
  PASSING t.XMLDATA
  COLUMNS IdView VARCHAR2(30) PATH '@IdView',
    CompId VARCHAR2(30) PATH '@CompId',
    attr_name VARCHAR2(30) PATH 'name(.)',
    attr_value VARCHAR2(90) PATH '.' 
) x
WHERE t.xmlkey = 'SRDB-XML-sample-1.xml';

我已将节点名称设为通用名称,因此它会根据您的问题所说的匹配所有ComponentType="Single structure";这意味着它匹配示例XML片段。

由于您的示例节点没有任何内容,我已经猜到了您希望attr_value的内容。

使用扩展片段:

<SRDBSW>
  <OBJ_DF>
    <SCOS_TM_DF IdView="1111" IsDirect="Y" CategoryFlag="0" OwnerFlag="0" ShortDescription="TC Packet Header Structure" ShortDescriptionCore="TC Packet Header Structure" LongDescription="Item: SCOS TM Packet" Mnemonic="SCOS TM Packet" Type="SCOS_TM" TpcfName="My TM packet" InterpretFlag="Both" DefOffsetTime="66" >
      <TM_STR_COMP_LIST>
        <TM_STR_COMP ComponentType="Single structure" CompId="TMSTABCDE" CompBytePos="0" CompBitPos="0" TimeOffset="0" SelectorParRef="MABCA" SelRawValue="0" />
      </TM_STR_COMP_LIST>
    </SCOS_TM_DF>
    <TC_STR_DF IdView="1112" IsDirect="Y" CategoryFlag="0" OwnerFlag="0" ShortDescription="TC Packet Header Structure" ShortDescriptionCore="TC Packet Header Structure" LongDescription="Item: SCOS TM Packet" Mnemonic="SCOS TM Packet" Type="SCOS_TM" TpcfName="My TM packet" InterpretFlag="Both" DefOffsetTime="66" >
      <TC_STR_COMP_LIST>
        <TC_STR_COMP ComponentType="Single structure" CompId="TCSTABCDE" CompBytePos="0" CompBitPos="0" TimeOffset="0" SelectorParRef="MABCA" SelRawValue="0">Test value</TC_STR_COMP>
      </TC_STR_COMP_LIST>
    </TC_STR_DF>
  </OBJ_DF>
</SRDBSW>

得到:

IDVIEW   COMPID          ATTR_NAME            ATTR_VALUE    
-------- --------------- -------------------- ---------------
1111     TMSTABCDE       TM_STR_COMP                         
1112     TCSTABCDE       TC_STR_COMP          Test value     

SQL Fiddle demo

根据您的注释,您现在需要IdView来自的元素名称,您可以将其作为生成元素中的附加属性获取:

SELECT x.*
FROM xmlimport t
CROSS JOIN XMLTABLE (q'#for $i in //*[@ComponentType = 'Single structure']
    return element {$i/name()} {attribute IdView {$i/../../@IdView},
      attribute TopName {$i/../../name()},
      $i }#'
  PASSING t.XMLDATA COLUMNS IdView VARCHAR2(30) PATH '@IdView',
    TopName VARCHAR2(30) PATH '@TopName',
    attr_name VARCHAR2(30) PATH 'name(.)',
    attr_value VARCHAR2(90) PATH '.' 
) x
WHERE t.xmlkey = 'SRDB-XML-sample-1.xml';

IDVIEW   TOPNAME         ATTR_NAME            ATTR_VALUE    
-------- --------------- -------------------- ---------------
1111     SCOS_TM_DF      TM_STR_COMP                         
1112     TC_STR_DF       TC_STR_COMP          Test value     

我也转而使用alternative quote syntax,这意味着您不必绕过Single structure值附近的单引号。你只需要一个绝对不会出现在实际字符串内的分隔符,在这种情况下就是XPath。我个人通常默认使用方括号,但由于那些确实出现在XPath中以进行属性匹配,我使用的是#

SQL Fiddle

答案 1 :(得分:0)

据我了解您要执行的操作,IdView应包含@IdView祖先的<SCOS_TM_DF>属性。

您正在使用从根节点(/../../../@IdView)开始的绝对路径,从那里您进一步提升(到根节点上方不存在的元素)。您可能想要做的是从当前上下文.升序,例如

IdView VARCHAR2(30) PATH './../../../@IdView'

此外,您在第三行中使用的XPath表达式与您的XML输入(SCOS_TM_DF轴步骤?)不匹配。由于您没有提供完整的文档结构,因此很难在此处提供更多详细信息。