以下代码在我的程序中执行得非常好。在这种情况下,我最终得到一个 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字符吗?如果是这样,我该如何实施?
您可以使用字符流:
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 值。