在 Oracle 中不使用命名空间的 XMLTable
XMLTable without using namespaces in Oracle
我正在尝试使用 PL/SQL 中的 XMLTable 提取 xml 值。
DECLARE
xdata XMLType := XMLType(
'<?xml version="1.0" encoding="UTF-8"?>
<stusMsg xmlns="http://www.my.namespace.com/src">
<messageHeader>
<sourceSystem>PFS</sourceSystem>
<originatingSystem>MRTI HKH</originatingSystem>
</messageHeader>
<messageDetail>
<TradeRef>1033796</TradeRef>
<TradeRefType>Ticket</TradeRefType>
<Company>MY_CMPY</Company>
<TradeGREF></TradeGREF>
<TradeType>TRD</TradeType>
<PriorityType>CRS</PriorityType>
<Priority>1</Priority>
</messageDetail>
</stusMsg>');
CURSOR get_data(x XMLType) IS
SELECT *
FROM XMLTABLE(xmlnamespaces(default 'http://www.my.namespace.com/src'),
'/stusMsg/messageDetail'
passing x
COLUMNS
TradeRef VARCHAR2(30) PATH 'TradeRef',
TradeRefType VARCHAR2(30) PATH 'TradeRefType');
BEGIN
FOR rec IN get_data(xdata) LOOP
dbms_output.put_line(rec.TradeRef);
dbms_output.put_line(rec.TradeRefType);
END LOOP;
END;
如果我不在 XMLTABLE
中使用 xmlnamespaces(default 'http://www.my.namespace.com/src')
并且 xml (xdata
) 中存在命名空间,则不会提取值。
有没有办法告诉 XMLTABLE
忽略命名空间?这样程序就不会依赖于 xmlnamespaces
如果只有默认命名空间,您可以从文档根目录中删除 xmlns
属性,而不是试图忽略命名空间:
DECLARE
v_dom DBMS_XMLDOM.DOMDocument;
xdata XMLTYPE := XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>
<stusMsg xmlns="http://www.my.namespace.com/src">
<messageHeader>
<sourceSystem>PFS</sourceSystem>
<originatingSystem>MRTI HKH</originatingSystem>
</messageHeader>
<messageDetail>
<TradeRef>1033796</TradeRef>
<TradeRefType>Ticket</TradeRefType>
<Company>MY_CMPY</Company>
<TradeGREF></TradeGREF>
<TradeType>TRD</TradeType>
<PriorityType>CRS</PriorityType>
<Priority>1</Priority>
</messageDetail>
</stusMsg>');
CURSOR get_data(x XMLType) IS
SELECT *
FROM XMLTABLE(
'/stusMsg/messageDetail'
passing x
COLUMNS
TradeRef VARCHAR2(30) PATH 'TradeRef',
TradeRefType VARCHAR2(30) PATH 'TradeRefType'
);
BEGIN
v_dom := DBMS_XMLDOM.NEWDOMDOCUMENT(xdata);
DBMS_XMLDOM.REMOVEATTRIBUTE(
DBMS_XMLDOM.GETDOCUMENTELEMENT(v_dom),
'xmlns'
);
xdata := DBMS_XMLDOM.GETXMLTYPE(v_dom);
FOR rec IN get_data(xdata) LOOP
dbms_output.put_line(rec.TradeRef);
dbms_output.put_line(rec.TradeRefType);
END LOOP;
END;
/
输出:
1033796
Ticket
db<>fiddle here
如果您真的不想遵守 XML 文档中的命名空间,您可以对所有节点引用使用通配符:
SELECT *
FROM XMLTABLE(
'/*:stusMsg/*:messageDetail'
passing x
COLUMNS
TradeRef VARCHAR2(30) PATH '*:TradeRef',
TradeRefType VARCHAR2(30) PATH '*:TradeRefType');
但这似乎不太理想;如果可以的话,我会正确使用它们。
我正在尝试使用 PL/SQL 中的 XMLTable 提取 xml 值。
DECLARE
xdata XMLType := XMLType(
'<?xml version="1.0" encoding="UTF-8"?>
<stusMsg xmlns="http://www.my.namespace.com/src">
<messageHeader>
<sourceSystem>PFS</sourceSystem>
<originatingSystem>MRTI HKH</originatingSystem>
</messageHeader>
<messageDetail>
<TradeRef>1033796</TradeRef>
<TradeRefType>Ticket</TradeRefType>
<Company>MY_CMPY</Company>
<TradeGREF></TradeGREF>
<TradeType>TRD</TradeType>
<PriorityType>CRS</PriorityType>
<Priority>1</Priority>
</messageDetail>
</stusMsg>');
CURSOR get_data(x XMLType) IS
SELECT *
FROM XMLTABLE(xmlnamespaces(default 'http://www.my.namespace.com/src'),
'/stusMsg/messageDetail'
passing x
COLUMNS
TradeRef VARCHAR2(30) PATH 'TradeRef',
TradeRefType VARCHAR2(30) PATH 'TradeRefType');
BEGIN
FOR rec IN get_data(xdata) LOOP
dbms_output.put_line(rec.TradeRef);
dbms_output.put_line(rec.TradeRefType);
END LOOP;
END;
如果我不在 XMLTABLE
中使用 xmlnamespaces(default 'http://www.my.namespace.com/src')
并且 xml (xdata
) 中存在命名空间,则不会提取值。
有没有办法告诉 XMLTABLE
忽略命名空间?这样程序就不会依赖于 xmlnamespaces
如果只有默认命名空间,您可以从文档根目录中删除 xmlns
属性,而不是试图忽略命名空间:
DECLARE
v_dom DBMS_XMLDOM.DOMDocument;
xdata XMLTYPE := XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>
<stusMsg xmlns="http://www.my.namespace.com/src">
<messageHeader>
<sourceSystem>PFS</sourceSystem>
<originatingSystem>MRTI HKH</originatingSystem>
</messageHeader>
<messageDetail>
<TradeRef>1033796</TradeRef>
<TradeRefType>Ticket</TradeRefType>
<Company>MY_CMPY</Company>
<TradeGREF></TradeGREF>
<TradeType>TRD</TradeType>
<PriorityType>CRS</PriorityType>
<Priority>1</Priority>
</messageDetail>
</stusMsg>');
CURSOR get_data(x XMLType) IS
SELECT *
FROM XMLTABLE(
'/stusMsg/messageDetail'
passing x
COLUMNS
TradeRef VARCHAR2(30) PATH 'TradeRef',
TradeRefType VARCHAR2(30) PATH 'TradeRefType'
);
BEGIN
v_dom := DBMS_XMLDOM.NEWDOMDOCUMENT(xdata);
DBMS_XMLDOM.REMOVEATTRIBUTE(
DBMS_XMLDOM.GETDOCUMENTELEMENT(v_dom),
'xmlns'
);
xdata := DBMS_XMLDOM.GETXMLTYPE(v_dom);
FOR rec IN get_data(xdata) LOOP
dbms_output.put_line(rec.TradeRef);
dbms_output.put_line(rec.TradeRefType);
END LOOP;
END;
/
输出:
1033796 Ticket
db<>fiddle here
如果您真的不想遵守 XML 文档中的命名空间,您可以对所有节点引用使用通配符:
SELECT *
FROM XMLTABLE(
'/*:stusMsg/*:messageDetail'
passing x
COLUMNS
TradeRef VARCHAR2(30) PATH '*:TradeRef',
TradeRefType VARCHAR2(30) PATH '*:TradeRefType');
但这似乎不太理想;如果可以的话,我会正确使用它们。