使用Oracle PLSQL,我已经到了一个点,我已经生成了许多XMLType类型的XML片段。我将这些存储在XMLTYPE类型的VARRAY中。我可以成功地将这些单独打印到文件中。
接下来我要做的是将所有这些片段融合在一起并将它们包装在另一个根元素中以生成单个文档。根据我的内容,如果我能够获得XMLSEQUENCETYPE,那么我可以将其传递给XMLCONCAT(..)并且它应该返回所有片段的XMLType级联。在此之后,它只是使用XMLELEMENT(..)添加根元素的情况。但是,我很难找到一种从我的VARRAY XMLTYPE中生成XMLSEQUENCETYPE的方法。
有谁知道如何做到这一点,以及我所采取的方法是否最好? (如果有人好奇,我正在尝试创建一个基本的dbunit类型框架。这个脚本的目的是创建一个可用于将XML DataSet输出到文件的工具,以后将其加载到单元测试中。) p>
这是plsql脚本:
set serveroutput on;
CREATE OR REPLACE TYPE rowset_query_type AS OBJECT (
table_name VARCHAR2(100),
query_string VARCHAR2(1024)
);
/
DECLARE
TYPE XML_Fragments_Type IS VARRAY(1000) OF XMLTYPE;
TYPE Rowset_Query_List_Type is VARRAY(1000) OF rowset_query_type;
outputDir VARCHAR(200) := 'ORACLE_FILE_DIR';
outputFile VARCHAR(200) := 'TestDataSet.xml';
qryCtx DBMS_XMLGEN.ctxHandle;
rowsetResultFragments XML_Fragments_Type;
rowsetQueries Rowset_Query_List_Type;
xmlResult xmltype;
rowsetQueryElement rowset_query_type;
output CLOB;
BEGIN
dbms_output.put_line('Exporting dataset...');
-- export files to data fixture
-- define fixtures
rowsetQueries := Rowset_Query_List_Type();
rowsetQueries.EXTEND(2);
rowsetQueries := Rowset_Query_List_Type(
rowset_query_type('person', 'select * from person'),
rowset_query_type('address','select * from address'));
rowsetResultFragments := XML_Fragments_Type();
rowsetResultFragments.EXTEND(rowsetQueries.count);
FOR i IN rowsetQueries.FIRST..rowsetQueries.LAST
LOOP
rowsetQueryElement := rowsetQueries(i);
dbms_output.put_line('Extracting dataset for table: ' || rowsetQueryElement.table_name || ' using query: ''' || rowsetQueryElement.query_string || '''');
qryCtx := dbms_xmlgen.newContext(rowsetQueryElement.query_string);
-- wrap the result up with a metadata tag containing the fixture tablename
select xmlelement(
"ROWSET_QUERY",
xmlattributes(rowsetQueryElement.table_name as "tableName"),
DBMS_XMLGEN.getXMLType(qryCtx)
)
into rowsetResultFragments(i)
from dual;
--close context
DBMS_XMLGEN.closeContext(qryCtx);
-- print the results to console
-- serialize the result for printing to output
SELECT XMLSERIALIZE(
CONTENT
rowsetResultFragments(i)
AS CLOB)
INTO output
FROM DUAL;
DBMS_OUTPUT.PUT_LINE(output);
END LOOP;
-- concatenate the set of rowsetQueries result fragments to a single result clob
-- ???
END;
/
答案 0 :(得分:3)
首先,将您的类型更改为SQL 1:
create or replace TYPE XML_Fragments_Type IS VARRAY(1000) OF XMLTYPE;
/
然后这样做
-- concatenate the set of rowsetQueries result fragments to a single result clob
-- ???
select xmlelement("root" ,xmlagg(column_value))
into xmlresult
from table(rowsetResultFragments);
例如:
SQL> create or replace TYPE XML_Fragments_Type IS VARRAY(1000) OF XMLTYPE;
2 /
Type created.
SQL> DECLARE
2
3 --TYPE XML_Fragments_Type IS VARRAY(1000) OF XMLTYPE;
4 TYPE Rowset_Query_List_Type is VARRAY(1000) OF rowset_query_type;
5
6 outputDir VARCHAR(200) := 'ORACLE_FILE_DIR';
7 outputFile VARCHAR(200) := 'TestDataSet.xml';
8
...
26 rowsetQueries := Rowset_Query_List_Type(
27 rowset_query_type('person', 'select table_name, owner from dba_tables where rownum = 1'),
28 rowset_query_type('address','select owner, type_name, attributes from dba_types where rownum = 1'));
29
...
56
57 select xmlelement("root" ,xmlagg(column_value))
58 into xmlresult
59 from table(rowsetResultFragments);
60 SELECT XMLSERIALIZE(
61 CONTENT
62 xmlresult
63 AS CLOB )
64 INTO output
65 FROM DUAL;
66 DBMS_OUTPUT.PUT_LINE(output);
67
68
69 END;
70 /
Exporting dataset...
Extracting dataset for table: person using query: 'select table_name, owner from dba_tables where rownum = 1'
Extracting dataset for table: address using query: 'select owner, type_name, attributes from dba_types where rownum = 1'
<root>
<ROWSET_QUERY tableName="person">
<ROWSET>
<ROW>
<TABLE_NAME>ICOL$</TABLE_NAME>
<OWNER>SYS</OWNER>
</ROW>
</ROWSET>
</ROWSET_QUERY>
<ROWSET_QUERY tableName="address">
<ROWSET>
<ROW>
<OWNER>CTXSYS</OWNER>
<TYPE_NAME>CATINDEXMETHODS</TYPE_NAME>
<ATTRIBUTES>3</ATTRIBUTES>
</ROW>
</ROWSET>
</ROWSET_QUERY>
</root>
答案 1 :(得分:2)
如果您没有使用这些片段,可以在循环中使用XMLCONCAT,然后在结尾使用XMLELEMENT:
SQL> DECLARE
2 TYPE Rowset_Query_List_Type IS VARRAY(1000) OF rowset_query_type;
3
4 outputDir VARCHAR(200) := 'ORACLE_FILE_DIR';
5 outputFile VARCHAR(200) := 'TestDataSet.xml';
6
7 qryCtx DBMS_XMLGEN.ctxHandle;
8 rowsetQueries Rowset_Query_List_Type;
9 xmlResult XMLTYPE;
10 rowsetQueryElement rowset_query_type;
11 BEGIN
12 -- define fixtures
13 rowsetQueries := Rowset_Query_List_Type(
14 rowset_query_type('person', 'select * from dual'),
15 rowset_query_type('address', 'select * from dual'));
16
17 FOR i IN rowsetQueries.FIRST .. rowsetQueries.LAST LOOP
18
19 rowsetQueryElement := rowsetQueries(i);
20 dbms_output.put_line('Extracting dataset for table: '
21 || rowsetQueryElement.table_name
22 || ' using query: '''
23 || rowsetQueryElement.query_string || '''');
24
25 qryCtx := dbms_xmlgen.newContext(rowsetQueryElement.query_string);
26
27 -- concatenate
28 SELECT xmlconcat(xmlResult,
29 xmlelement(
30 "ROWSET_QUERY",
31 xmlattributes(
32 rowsetQueryElement.table_name AS "tableName"),
33 DBMS_XMLGEN.getXMLType(qryCtx)))
34 INTO xmlResult
35 FROM dual;
36
37 --close context
38 DBMS_XMLGEN.closeContext(qryCtx);
39
40 END LOOP;
41
42 -- root element
43 SELECT xmlelement(ROOT, xmlresult) INTO xmlresult FROM dual;
44
45 dbms_output.put_line('result:');
46 DBMS_OUTPUT.PUT_LINE(xmlResult.getClobVal());
47
48 END;
49 /
Extracting dataset for table: person using query: 'select * from dual'
Extracting dataset for table: address using query: 'select * from dual'
result:
<ROOT><ROWSET_QUERY tableName="person"><ROWSET>
<ROW>
<DUMMY>X</DUMMY>
</ROW>
</ROWSET>
</ROWSET_QUERY><ROWSET_QUERY tableName="address"><ROWSET>
<ROW>
<DUMMY>X</DUMMY>
</ROW>
</ROWSET>
</ROWSET_QUERY></ROOT>
PL/SQL procedure successfully completed