Следующий код отлично работает в моей программе. В этом контексте я получаю 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
, но нарушает ограничение в 32 КБ, установленное типом данных VARCHAR2
PL/SQL. Поскольку функция Dbms_XmlDom.createTextNode()
определена с типом данных VARCHAR2
, во время выполнения я получаю сообщение об ошибке, сообщающее, что буфер символьной строки слишком мал.
Поддерживает ли Dbms_XmlDom
содержание тегов >32 тыс. символов? И если да, то как мне это реализовать?
Вы можете использовать поток символов:
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 для получения выходного потока:
Эта функция возвращает экземпляр типа PL/SQL XMLCHARACTEROUTPUTSTREAM, в который вызывающая сторона может записать значение узла. Тип данных узла может быть любым допустимым типом данных XDB. Если тип не является символьным или CLOB, символьные данные, записанные в поток, преобразуются в тип данных узла. Если тип данных узла символьный или CLOB, то символьные данные, записанные в поток, преобразуются из набора символов сеанса PL/SQL в набор символов узла.
Затем он перебирает CLOB и записывает его в этот поток частями, которые помещаются в буфер varchar2
.
рабочий пример показывает исходный код и длину DomText (через DomNode), затем этот подход с той же строкой, а затем снова с гораздо большим значением CLOB (со вторым потоком для чтения значения узла обратно для проверки его длина).