我有一张这样的表:
COL1 COL2 COL3
---------- ---------- ----------
T1 Direct M1
T1 Direct M2
T1 List M3
M3 Direct M4
M3 Direct M5
M3 List M6
M6 Direct M7
M6 Direct M8
T2 Direct M9
Col2 - '直接'说Col3是Col1的直接孩子。
Col2 - '列表'说Col3是Col1的子列表。
因此,对于上述示例,T1具有M1,M2作为直接子项,M3是子子项。再次,M3有M4,M5直接孩子和M6作为子孩子。它继续。
我需要在上面使用Oracle查询转换为XML,如下所示。
<ROOT>
<T1>
<M1/>
<M2/>
<M3>
<M4/>
<M5/>
<M6>
<M7/>
<M8/>
<M6/>
<M3/>
<T1/>
<T2>
<M9 />
<T2>
</ROOT>
如何获得上述XML结果?我允许在表格中添加其他条目,以便将整个xml保留在<ROOT>
代码中。
答案 0 :(得分:2)
XML节点名称不能以数字开头,因此您显示的输出无效。您可以使用不同的名称获取结构,或使用这些值来获取属性。
从获取层次结构的查询开始(col2
似乎与此无关,它只是描述仅存在于col1
和col3
的层次结构:
select lpad(' ', level) || col3
from t42
connect by col1 = prior col3 and col1 != col3
start with col1 = col3;
LPAD('',LEVEL)||COL3
--------------------------------------------------------------------------------
1
2
3
4
5
6
7
8
然后,您可以将它们转换为XML元素,在这种情况下使用固定字符,以使它们成为有效名称:
select level, xmlelement(evalname 'x' || col3)
from t42
connect by col1 = prior col3 and col1 != col3
start with col1 = col3;
LEVEL XMLELEMENT(EVALNAME'X'||COL3)
---------- --------------------------------------------------------------------------------
1 <x1></x1>
2 <x2></x2>
2 <x3></x3>
3 <x4></x4>
3 <x5></x5>
3 <x6></x6>
4 <x7></x7>
4 <x8></x8>
然后,您可以在dbms_xmlgen.newContextFromHierarchy
call中使用该查询:
select dbms_xmlgen.getxmltype(
dbms_xmlgen.newcontextfromhierarchy(
q'[select level, xmlelement(evalname 'x' || col3)
from t42
connect by col1 = prior col3 and col1 != col3
start with col1 = col3]')) as result
from dual;
RESULT
--------------------------------------------------------------------------------
<?xml version="1.0"?>
<x1>
<x2/>
<x3>
<x4/>
<x5/>
<x6>
<x7/>
<x8/>
</x6>
</x3>
</x1>
或作为属性:
select dbms_xmlgen.getxmltype(
dbms_xmlgen.newcontextfromhierarchy(
q'[select level,
xmlelement("x", xmlattributes(level as "level", col3 as "col3"))
from t42
connect by col1 = prior col3 and col1 != col3
start with col1 = col3]')) as result
from dual;
RESULT
--------------------------------------------------------------------------------
<?xml version="1.0"?>
<x level="1" col3="1">
<x level="2" col3="2"/>
<x level="2" col3="3">
<x level="3" col3="4"/>
<x level="3" col3="5"/>
<x level="3" col3="6">
<x level="4" col3="7"/>
<x level="4" col3="8"/>
</x>
</x>
</x>
如果您真的想要,可以将第一个版本转换为字符串并删除虚拟字符:
select replace(
dbms_xmlgen.getxmltype(
dbms_xmlgen.newcontextfromhierarchy(
q'[select level, xmlelement(evalname 'x' || col3)
from t42
connect by col1 = prior col3 and col1 != col3
start with col1 = col3]')).getstringval(),
'x', null) as result
from dual;
RESULT
--------------------------------------------------------------------------------
<?ml version="1.0"?>
<1>
<2/>
<3>
<4/>
<5/>
<6>
<7/>
<8/>
</6>
</3>
</1>
或大型文档的等效getclobval()
。但现在这是一个字符串,而不是真正的XML;如果您尝试将其转换回XMLType,则会收到类似“LPX-00231:在名称或Nmtoken中找到的无效字符49('1')”的错误。无论如何,你可能会接受一些东西。