CLOB转XML解析失败求助:ORA-31011等报错排查
解决CLOB转XML时的ORA-31011/LPX-00601解析错误
让我们一步步排查你的问题:
错误原因分析
从报错信息LPX-00601: Invalid token in: '/KrediBilgi/'可以直接定位到问题根源:
- XPath语法错误:你在
Extract(l_xmlType,'/KrediBilgi/')里写的XPath末尾多了一个斜杠,这种写法不符合XPath规范,XML解析器无法识别这个无效的token,直接导致了解析失败。 - 过时函数的使用:
ExtractValue和XMLSequence在Oracle 12c及以后的版本已经被官方标记为废弃(deprecated),虽然旧版本还能勉强运行,但兼容性和稳定性都不如推荐的替代方案。 - 潜在的XML结构不匹配:如果你的输入XML不是以多个
<KrediBilgi>作为根节点,而是被包裹在一个父节点(比如<KrediBilgileri>)里,原代码的XPath也会无法正确定位到目标节点。
解决方法
我会给你两种修复方案,一种是针对现有代码的最小修改,另一种是使用Oracle推荐的现代写法:
方案1:最小修改现有代码
只需要修正XPath的语法错误,去掉末尾的斜杠即可:
procedure parse_xml(response in CLOB) is l_xmlType XMLTYPE; begin l_xmlType := XMLTYPE.CreateXML(response); FOR r IN ( SELECT ExtractValue(Value(p),'/KrediBilgi/Durum/text()') as durum ,ExtractValue(Value(p),'/KrediBilgi/GuncelRisk/text()') as risk ,ExtractValue(Value(p),'/KrediBilgi/GuncelRiskTarih/text()') as tarih ,ExtractValue(Value(p),'/KrediBilgi/KrediHesapNo/text()') as hesapNo ,ExtractValue(Value(p),'/KrediBilgi/KrediKod/text()') as krediKod ,ExtractValue(Value(p),'/KrediBilgi/KrediKonu/text()') as krediKonu ,ExtractValue(Value(p),'/KrediBilgi/KrediTur/text()') as krediTur ,ExtractValue(Value(p),'/KrediBilgi/KrediTutar/text()') as krediTutar ,ExtractValue(Value(p),'/KrediBilgi/PbKod/text()') as pbKod ,ExtractValue(Value(p),'/KrediBilgi/ProjeKod/text()') as projeKod -- 去掉XPath末尾的斜杠 FROM TABLE(XMLSequence(Extract(l_xmlType,'/KrediBilgi'))) p ) LOOP dbms_output.put_line(r.durum); dbms_output.put_line(r.risk); dbms_output.put_line(r.tarih); dbms_output.put_line(r.hesapNo); dbms_output.put_line(r.krediKod); dbms_output.put_line(r.krediKonu); dbms_output.put_line(r.krediTur); dbms_output.put_line(r.krediTutar); dbms_output.put_line(r.pbKod); dbms_output.put_line(r.projeKod); END LOOP; end parse_xml;
方案2:使用Oracle推荐的XMLTable写法(推荐)
既然ExtractValue和XMLSequence已经废弃,换成XMLTable不仅能避免潜在的兼容性问题,代码可读性也更好:
procedure parse_xml(response in CLOB) is l_xmlType XMLTYPE; begin l_xmlType := XMLTYPE.CreateXML(response); FOR r IN ( SELECT durum, risk, tarih, hesapNo, krediKod, krediKonu, krediTur, krediTutar, pbKod, projeKod FROM XMLTable( -- 这里的XPath根据你的实际XML结构调整,如果有父节点就写成'/KrediBilgileri/KrediBilgi' '/KrediBilgi' PASSING l_xmlType COLUMNS durum VARCHAR2(100) PATH 'Durum/text()', risk VARCHAR2(100) PATH 'GuncelRisk/text()', tarih DATE PATH 'GuncelRiskTarih/text()', hesapNo VARCHAR2(100) PATH 'KrediHesapNo/text()', krediKod VARCHAR2(100) PATH 'KrediKod/text()', krediKonu VARCHAR2(200) PATH 'KrediKonu/text()', krediTur VARCHAR2(100) PATH 'KrediTur/text()', krediTutar NUMBER PATH 'KrediTutar/text()', pbKod VARCHAR2(100) PATH 'PbKod/text()', projeKod VARCHAR2(100) PATH 'ProjeKod/text()' ) ) LOOP dbms_output.put_line(r.durum); dbms_output.put_line(r.risk); dbms_output.put_line(r.tarih); dbms_output.put_line(r.hesapNo); dbms_output.put_line(r.krediKod); dbms_output.put_line(r.krediKonu); dbms_output.put_line(r.krediTur); dbms_output.put_line(r.krediTutar); dbms_output.put_line(r.pbKod); dbms_output.put_line(r.projeKod); END LOOP; end parse_xml;
额外注意事项
- 如果你的输入XML结构是类似下面这种有父节点的情况:
记得把XPath改成<KrediBilgileri> <KrediBilgi>...</KrediBilgi> <KrediBilgi>...</KrediBilgi> </KrediBilgileri>'/KrediBilgileri/KrediBilgi',否则会找不到节点。 - 确保传入的CLOB数据是合法的XML格式,比如没有未闭合的标签、特殊字符未转义等问题,这些也可能触发解析错误。
内容的提问来源于stack exchange,提问作者burak ramazan
相关产品推荐
相关产品推荐

