use*_*472 7 sql oracle parsing namespaces xmltype
我在使用Oracle SQL和XML时遇到了麻烦.
我将从外部系统获取大量格式良好的XML数据,以解析,解释和填充一些表.我使用XMLTable编写了一个解决方案,它在表格的视图中列出了有问题的xml clob列和一些审计信息和内容(我想保持这种方式).
NAMESPACES给我做恶梦.显然我不能把它们放在xmlnamespaces子句中,因为我永远不会知道它们会是什么.荒谬!交付的相同类型的项目可能在不同的时间点具有不同的名称空间.没有有限的清单.甚至默认的xmlns都不是常量.
到目前为止,我提出的最佳工作解决方案是一组regexp_replace(确切地说是3),在解析之前擦除所有命名空间.但表现是一个巨大的问题.
当然有一些我想念的聪明人?
我知道这已经很老了,但我今天发现它并记得我在尝试处理命名空间XML时遇到的痛苦.我的解决方案是使用XSLT转换删除命名空间并将其作为普通的旧XML进行处理.我以前做的这个功能是:
function remove_namespace( i_xml in xmltype )
return xmltype
is
v_xml xmltype default i_xml;
v_xsl varchar2(32767);
begin
v_xsl := '<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="*">
<!-- remove element prefix (if any) -->
<xsl:element name="{local-name()}">
<!-- process attributes -->
<xsl:for-each select="@*">
<!-- remove attribute prefix (if any) -->
<!-- this if filters out any xmlns="" atts that have no
namespace prefix in the xml -->
<xsl:if test="(local-name() != ''xmlns'')">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:if>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>';
return v_xml.transform(xmltype(v_xsl));
end;
Run Code Online (Sandbox Code Playgroud)