Oracle 11.2
以下是我在XMLType列上运行的XMLQuery的缩减版本.当我运行查询(它只是解析并重新创建存储的XML)时,不需要的默认和tsip命名空间就被插入到父进程的子元素中.请注意,tsxm命名空间没有被插入,这是因为它不等于默认的命名空间这个查询什么都不做,也可以很容易地被重写,但是真正(大得多的)查询使用同样的方法,所以这就是为什么我以此格式发布问题.
创建表:
CREATE TABLE XML_DOCUMENT_TMP ( DOCUMENT_ID NUMBER(12) NOT NULL,XML_DATA SYS.XMLTYPE NOT NULL,CREATED_DATE TIMESTAMP(6) NOT NULL );
插入一些数据(必须具有名称空间):
insert into XML_DOCUMENT_TMP (document_id,created_date,xml_data) values(1,sysdate,'<patent xmlns="http://schemas.thomson.com/ts/20041221/tsip" xmlns:tsip="http://schemas.thomson.com/ts/20041221/tsip" xmlns:tsxm="http://schemas.thomson.com/ts/20041221/tsxm" tsip:action="replace" tsip:cc="CA" tsip:se="2715340" tsip:ki="C"> <accessions tsip:action="replace"> <accession tsip:src="wila" tsip:type="key">CA-2715340-C</accession> <accession tsip:src="tscm" tsip:type="tscmKey">CA-2715340-C-20150804</accession> </accessions> <claimed tsip:action="replace"> < claimsTsxm tsip:lang="en"> <tsxm:heading tsxm:align="left">We Claim:</tsxm:heading> <claimTsxm tsip:no="1" tsxm:num="1" tsip:type="main">1. power. </claimTsxm> </claimsTsxm> </claimed> </patent> ');
运行XMLQuery:
WITH tmpTable AS ( SELECT * FROM XML_DOCUMENT_TMP cm ) SELECT tt.xml_data,XMLQuery('declare default element namespace "http://schemas.thomson.com/ts/20041221/tsip"; declare namespace tsip="http://schemas.thomson.com/ts/20041221/tsip"; declare namespace tsxm="http://schemas.thomson.com/ts/20041221/tsxm"; return <patent>{$m/*:patent/@*} { for $i in $m/*:patent/* return $i } </patent>' PASSING tt.xml_data as "m" RETURNING CONTENT) newXml FROM tmpTable tt WHERE tt.document_id in (1);
返回:
<patent xmlns="http://schemas.thomson.com/ts/20041221/tsip" xmlns:tsip="http://schemas.thomson.com/ts/20041221/tsip" tsip:action="replace" tsip:cc="CA" tsip:se="2715340" tsip:ki="C"> <accessions xmlns="http://schemas.thomson.com/ts/20041221/tsip" xmlns:tsip="http://schemas.thomson.com/ts/20041221/tsip" tsip:action="replace"> <accession tsip:src="wila" tsip:type="key">CA-2715340-C</accession> <accession tsip:src="tscm" tsip:type="tscmKey">CA-2715340-C-20150804</accession> </accessions> <claimed xmlns="http://schemas.thomson.com/ts/20041221/tsip" xmlns:tsip="http://schemas.thomson.com/ts/20041221/tsip" tsip:action="replace"> <claimsTsxm tsip:lang="en"> <tsxm:heading xmlns:tsxm="http://schemas.thomson.com/ts/20041221/tsip" tsxm:align="left">We Claim:</tsxm:heading> <claimTsxm tsip:no="1" xmlns:tsxm="http://schemas.thomson.com/ts/20041221/tsip" tsxm:num="1" tsip:type="main">1. power.</claimTsxm> </claimsTsxm> </claimed>
如何摆脱在加入和声明的元素中创建的不必要的命名空间.
任何建议赞赏.
如果您使用命名空间的各种值,您可以看到,顶部<专利>级别命名空间由于您所做的声明而被声明和包含,在子元素级别,此信息不会以您期待的方式使用.
XQuery正在根据在该执行循环中被考虑的节点中使用的命名空间来提取命名空间,而与整个文档无关.这就是为什么每次XQuery循环时都会重新声明.
其他文章解释说,你所要做的就是“解析”数据以及“提取”它,这在一定程度上是真的,所以XSLT是正确的工具,而不是XQuery.
我发现一个外部链接,它具有剥离命名空间的XQuery方式,因此返回“raw”XML是here.
将该代码应用到您的XQuery已经让我:
SELECT xmlquery('xquery version "1.0"; (: :) declare default element namespace "http://www.somewherein.uk/ns/1.0"; (: :) declare function local:strip-namespace($inputRequest as element()) as element() { element {xs:QName(local-name($inputRequest ))} { for $child in $inputRequest /(@*,node()) return if ($child instance of element()) then local:strip-namespace($child) else $child } }; (: :) <patent> { for $s in /*:patent/* return local:strip-namespace($s) } </patent>' PASSING cmf.XML_DATA RETURNING content) FROM XML_DOCUMENT_TMP cmf WHERE cmf.DOCUMENT_ID=1
一些进一步的编辑让我到下面,我认为是你以后(在专利级定义的命名空间)
SELECT xmlquery('xquery version "1.0"; (: :) declare default element namespace "http://www.somewherein.uk/ns/1.0"; (: :) declare function local:strip-namespace($inputRequest as element()) as element() { element {fn:name($inputRequest)} { for $child in $inputRequest /(@*,node()) return if ($child instance of element()) then local:strip-namespace($child) else $child } }; (: :) <patent> { for $s in /(*:patent,node()) return local:strip-namespace($s) } </patent>' PASSING cmf.XML_DATA RETURNING content) FROM XML_DOCUMENT_TMP cmf WHERE cmf.DOCUMENT_ID=1;
如下所述,由于XPath中的一些问题,导致循环代码中的一些重复.这也意味着txsm命名空间被声明了几次; XQuery声明它是“第一次”遇到使用它的命名空间,因为它走那棵树分支意味着如果有兄弟姐妹使用ns,那么它将被声明多次.通过将声明的显式布局移回到父节点,我们可以消除这一点.
SELECT xmlquery('xquery version "1.0"; (: :) declare default element namespace "http://schemas.thomson.com/ts/20041221/tsip"; (: :) declare namespace tsip="http://schemas.thomson.com/ts/20041221/tsip"; (: :) declare namespace tsxm="http://schemas.thomson.com/ts/20041221/tsxm"; (: :) declare function local:strip-namespace($inputRequest as element()) as element() { element {fn:name($inputRequest)} { for $child in $inputRequest /(@*,node()) return if ($child instance of element()) then local:strip-namespace($child) else $child } }; (: :) <patent xmlns:tsxm="http://schemas.thomson.com/ts/20041221/tsxm" xmlns:tsip="http://schemas.thomson.com/ts/20041221/tsip"> { for $s in /*:patent/* return local:strip-namespace($s) } </patent>' PASSING cmf.XML_DATA RETURNING content) FROM XML_DOCUMENT_TMP cmf WHERE cmf.DOCUMENT_ID=1;