使用 `Dbms_XmlDom` 将 CLOB 数据添加到 XML

问题描述 投票:0回答:1

以下代码在我的程序中执行得非常好。在这种情况下,我最终得到一个 XML 文件,其中包含一个标签,其内容为“非常非常长的字符串”。

DECLARE
   doc_           dbms_xmlDom.DomDocument := := Dbms_XmlDom.newDomDocument;
   nd_txt_        dbms_xmldom.DOMText;
   text_content_  CLOB := 'a very very very long string';
BEGIN
   --- blah blah blah, lots of code goes here...

   nd_txt_ := Dbms_XmlDom.createTextNode (doc_, text_content_);

END;

但是您会注意到我已将

text_content_
变量定义为
CLOB
,而不是
VARCHAR2
。我在实际程序中所做的是对 PDF 文件进行 Base-64 编码并将其分配给
text_content_
。生成的 base-64 字符串非常适合
CLOB
,但打破了 PL/SQL 的
VARCHAR2
数据类型施加的 32k 限制。由于函数
Dbms_XmlDom.createTextNode()
是使用
VARCHAR2
数据类型定义的,因此在运行时我收到一条错误消息,指出字符串缓冲区太小。

Dbms_XmlDom
支持标签内容>32k字符吗?如果是这样,我该如何实施?

oracle plsql
1个回答
0
投票

您可以使用字符流:

DECLARE
   doc_           dbms_xmlDom.DomDocument := Dbms_XmlDom.newDomDocument;
   nd_txt_        dbms_xmlDom.DomText;
   text_content_  CLOB := 'a very very very long string';

   nd_            dbms_xmlDom.DomNode;
   stream_        sys.utl_characteroutputstream;
   pos_           pls_integer := 1;
   amt_           pls_integer := 4000;
   buf_           varchar2(4000);
BEGIN
   nd_txt_ := dbms_xmlDom.createTextNode (doc_, '');

   nd_ := dbms_xmlDom.makeNode(nd_txt_);
   stream_ := dbms_xmlDom.setNodeValueAsCharacterStream(nd_);
   while pos_ <= dbms_lob.getlength(text_content_) loop
      dbms_lob.read(text_content_, amt_, pos_, buf_);
      pos_ := pos_ + amt_;
      stream_.write(buf_, 0, amt_);
   end loop;
   stream_.close;
END;
/

从一个空的 DomText 开始,将其转换为 DomNode,然后调用

setNodeValueAsCharacterStream
来获取输出流。

然后循环 CLOB 并将其以适合

varchar2
缓冲区的块形式写入流。

fiddle 显示您的原始代码和 DomText 的长度(通过 DomNode),然后使用相同的字符串,然后再次使用更大的 CLOB 值。

© www.soinside.com 2019 - 2024. All rights reserved.