借助XMLTABLE从带命名空间的XML提取属性值遇“无数据”问题求助
问题分析与解决
你的代码报错是因为命名空间的使用范围搞错了:只有<eldp09>元素属于http://schemas.cssz.cz/ELDP09命名空间,而外层的<xmlZdroj>和<zdrojdok>是无命名空间的;另外XML里的属性默认不会继承父元素的命名空间,所以sqnr、yer这些属性也不属于这个命名空间。
修正后的代码如下:
SET SERVEROUTPUT ON DECLARE xmldocX XMLType; r1X VARCHAR2(100); r2X VARCHAR2(100); BEGIN xmldocX:=XMLType('<xmlZdroj> <zdrojdok typ="ELDP09"> <eldp09 xmlns="http://schemas.cssz.cz/ELDP09" sqnr="1" yer="2009" typ="01" dep="660" nam="HB"></eldp09> </zdrojdok> </xmlZdroj>'); SELECT sqnr,yer INTO r1X,r2X FROM xmltable(XMLNamespaces('http://schemas.cssz.cz/ELDP09' AS "xx"), '/xmlZdroj/zdrojdok/xx:eldp09' -- 只有eldp09加xx前缀 PASSING xmldocX COLUMNS sqnr VARCHAR2(10) PATH '@sqnr', -- 属性不带命名空间前缀 yer VARCHAR2(10) PATH '@yer' ); DBMS_OUTPUT.PUT_LINE('result: '||nvl(r1X,'null')||' '||nvl(r2X,'null')); END; /
关键修正点:
- XPath路径:只给
<eldp09>加上命名空间前缀xx:,外层的<xmlZdroj>和<zdrojdok>保持原样(因为它们不在目标命名空间下) - 属性提取路径:去掉
@xx:前缀,直接用@sqnr、@yer,因为这些属性没有被指定到任何命名空间中
如果你想用默认命名空间简化写法,也可以这么改(把目标命名空间设为默认,但注意只在<eldp09>上生效):
SET SERVEROUTPUT ON DECLARE xmldocX XMLType; r1X VARCHAR2(100); r2X VARCHAR2(100); BEGIN xmldocX:=XMLType('<xmlZdroj> <zdrojdok typ="ELDP09"> <eldp09 xmlns="http://schemas.cssz.cz/ELDP09" sqnr="1" yer="2009" typ="01" dep="660" nam="HB"></eldp09> </zdrojdok> </xmlZdroj>'); SELECT sqnr,yer INTO r1X,r2X FROM xmltable(XMLNamespaces(default 'http://schemas.cssz.cz/ELDP09'), '/xmlZdroj/zdrojdok/eldp09' -- 默认命名空间下的eldp09无需前缀 PASSING xmldocX COLUMNS sqnr VARCHAR2(10) PATH '@sqnr', yer VARCHAR2(10) PATH '@yer' ); DBMS_OUTPUT.PUT_LINE('result: '||nvl(r1X,'null')||' '||nvl(r2X,'null')); END; /
这两种写法都能正常提取到sqnr=1和yer=2009的结果。
内容的提问来源于stack exchange,提问作者papo308
相关产品推荐
相关产品推荐

