Oracle 11.2
以下是在XMLQuery
列上运行的XMLType
i的缩减版本。当我运行查询时,只需解析并重新创建存储的XML
,不需要的默认和tsip名称空间就会插入父项的子元素中。请注意,tsxm名称空间不会被插入,这是因为它不等于默认名称空间这个查询什么也不做,可以轻松地重写,但真正的(更大)查询使用相同的方法,所以这就是为什么我&#39 ; m以这种格式发布问题。
创建表格:
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
:
请注意{@ 3}}
需要名称空间通配符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>
如何摆脱在种质和声明的元素中创建的不需要的命名空间。 任何建议表示赞赏。
答案 0 :(得分:2)
如果您使用命名空间的各种值,您可以看到,由于您所做的声明,声明和包含命名空间的顶级<patent>
级别,在子元素级别,此信息不是&#39 ; t以您期望的方式使用。
XQuery基于在执行循环中考虑的节点中使用的名称空间来提取名称空间,与整个文档无关。这就是他们重新宣布&#34;每次XQuery绕过循环。
其他文章解释说,您尝试做的是&#34; Parse&#34;数据以及&#34;提取&#34;它,这在某种程度上是正确的,所以XSLT是正确的工具,而不是XQuery。
我找到了一个外部链接,它有一个XQuery方式来剥离命名空间,所以返回你的&#34; raw&#34; 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
进一步编辑让我进入下面,我认为你所追求的是(在patent
级定义的名称空间)
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第一次声明它&#34;#34;它会遇到使用它的命名空间,因为它走过那个树枝意味着如果有兄弟姐妹使用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;
答案 1 :(得分:1)
稍微修改@Graham Nicol的第二个解决方案,这似乎给出了正确答案:
SELECT xmlquery('xquery version "1.0";
declare default element namespace
"http://schemas.thomson.com/ts/20041221/tsip";
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>{/*: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;