我在Oracle中从数据库返回了以下类型的结果集:
**Name Type SubName Number**
test B tim 1
test B jfd 2
testV I rr 1
testV I sim 2
dsgsg B sgsg 1
dsgsg B sfsfssfsffs 2
我想要的是使用SQL来操作此结果来创建此类型的XML
<NameList>
<Name/>
<Type/>
<SubNameList>
<SubName>
<Name/>
<Number/>
</SubName>
</SubNameList>
</NameList>
例如:对于结果集的前两个记录具有相同的名称,因此XML将为:
<NameList>
<Name>test</Name>
<Type>B</Type>
<SubNameList>
<SubName>
<Name>tim</Name>
<Number>1</Number>
</SubName>
<SubName>
<Name>jfd</Name>
<Number>2</Number>
</SubName>
</SubNameList>
</NameList>
到目前为止我做了什么: 我有两张桌子:
TABLE1
**ID NAME KEY**
1 test 101
1 testV 102
1 dsgsg 103
TABLE2
**ID SUBNAME TYPE NUMBER KEY**
1 tim B 1 101
1 jfd B 2 101
1 rr I 1 102
1 sim I 2 102
1 sgsg B 1 103
1 sfsfssfsffs B 2 103
SQL:
Select A.NAME, B.TYPE, B.SUBNAME, B.NUMBER
FROM TABLE1 A INNER JOIN TABLE2 B
ON A.ID = B.ID WHERE A.ID = '1';
我在oracle中使用XMLELEMENT()创建了XML:
SET SERVEROUTPUT ON;
DECLARE NAME_XML XMLTYPE;
v_offset number := 1;
v_chunk_size number := 255;
BEGIN
Select XMLAGG(XMLELEMENT("NAMELIST",
XMLELEMENT("Name", A.NAME),
XMLELEMENT("Type", B.TYPE),
XMLELEMENT("SubName", B.SUBNAME),
XMLELEMENT("Number", B.NUMBER)))
INTO NAME_XML
FROM TABLE1 A INNER JOIN TABLE2 B
ON A.ID = B.ID WHERE A.ID = '1';
loop
exit when v_offset > dbms_lob.getlength(NAME_XML.getClobVal());
dbms_output.put_line( dbms_lob.substr(NAME_XML.getClobVal(),
v_chunk_size, v_offset ) );
v_offset := v_offset + v_chunk_size;
end loop;
END;
正在创建此类型的XML:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<NAMELIST>
<Name>test</Name>
<Type>B</Type>
<SubName>tim</SubName>
<Number>1</Number>
</NAMELIST>
.
.
.
.
.
<NAMELIST>
<Name>dsgsg</Name>
<Type>B</Type>
<SubName>sfsfssfsffs</SubName>
<Number>2</Number>
</NAMELIST>
</root>
如何实现此类型的XML格式:
<NameList>
<Name>test</Name>
<Type>B</Type>
<SubNameList>
<SubName>
<Name>tim</Name>
<Number>1</Number>
</SubName>
<SubName>
<Name>jfd</Name>
<Number>2</Number>
</SubName>
</SubNameList>
</NameList>
....
....
....
....
任何输入都会有所帮助。
答案 0 :(得分:0)
您可以使用以下程序:
CREATE OR REPLACE PROCEDURE MakePrettyXml(xmlString IN OUT NOCOPY CLOB, intent IN VARCHAR2 DEFAULT 'yes') IS
xmlDocFragment DBMS_XMLDOM.DOMDOCUMENTFRAGMENT;
xslProc DBMS_XSLPROCESSOR.PROCESSOR;
xsl DBMS_XSLPROCESSOR.STYLESHEET;
xmlStringOut CLOB;
BEGIN
DBMS_LOB.CREATETEMPORARY(xmlStringOut, TRUE);
xslProc := DBMS_XSLPROCESSOR.NEWPROCESSOR;
xsl := DBMS_XSLPROCESSOR.NEWSTYLESHEET(
'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">'||
'<xsl:output method="xml" indent="'||intent||'"/>'||
'<xsl:template match="@*|node( )">'||
'<xsl:copy>'||
'<xsl:apply-templates select="@*|node( )"/>'||
'</xsl:copy>'||
'</xsl:template>'||
'</xsl:stylesheet>', NULL);
xmlDocFragment := DBMS_XSLPROCESSOR.PROCESSXSL(p => xslProc, ss => xsl, cl => xmlString);
DBMS_XMLDOM.WRITETOCLOB(DBMS_XMLDOM.MAKENODE(xmlDocFragment), xmlStringOut);
DBMS_XSLPROCESSOR.FREESTYLESHEET(xsl);
DBMS_XSLPROCESSOR.FREEPROCESSOR(xslProc);
xmlString := xmlStringOut;
DBMS_LOB.FREETEMPORARY(xmlStringOut);
END MakePrettyXml;
结果:
DECLARE
xmlString CLOB := '<root><NAMELIST>
<Name>test</Name><Type>B</Type><SubName>tim</SubName><Number>1</Number>
</NAMELIST>
<NAMELIST>
<Name>dsgsg</Name>
<Type>B</Type><SubName>sfsfssfsffs</SubName>
<Number>2</Number>
</NAMELIST>
</root>';
BEGIN
MakePrettyXml(xmlString, 'no');
DBMS_OUTPUT.PUT_LINE(xmlString);
MakePrettyXml(xmlString);
DBMS_OUTPUT.PUT_LINE(xmlString);
END;
<root>
<NAMELIST>
<Name>test</Name>
<Type>B</Type>
<SubName>tim</SubName>
<Number>1</Number>
</NAMELIST>
<NAMELIST>
<Name>dsgsg</Name>
<Type>B</Type>
<SubName>sfsfssfsffs</SubName>
<Number>2</Number>
</NAMELIST>
</root>
<root>
<NAMELIST>
<Name>test</Name>
<Type>B</Type>
<SubName>tim</SubName>
<Number>1</Number>
</NAMELIST>
<NAMELIST>
<Name>dsgsg</Name>
<Type>B</Type>
<SubName>sfsfssfsffs</SubName>
<Number>2</Number>
</NAMELIST>
</root>
<强>更新强>
我希望您的问题与XML内容有关,而不是格式。在这种情况下尝试(未测试)
Select XMLELEMENT("NameList",
XMLELEMENT("Name", A.NAME),
XMLELEMENT("Type", B.TYPE),
XMLELEMENT("SubNameList",
XMLAGG(XMLELEMENT("SubName",
XMLELEMENT("Name", B.NAME)
XMLELEMENT("Number", B.NUMBER))))
)
INTO NAME_XML
FROM TABLE1 A INNER JOIN TABLE2 B
ON A.ID = B.ID WHERE A.ID = '1';