Ответ 1
Если вы играете с различными значениями пространств имен, вы можете видеть, что в то время как верхний уровень <patent>
пространства имен объявляются и включаются из-за заявлений, которые вы делаете, на уровне дочерних элементов эта информация не используется в как вы ожидаете.
XQuery извлекает пространства имен на основе тех, которые используются в узлах, которые рассматриваются в этом цикле выполнения, независимо от документов в целом. Вот почему они получают "повторно объявленные" каждый раз, когда XQuery обходит цикл.
В других статьях объясняется, что то, что вы пытаетесь сделать, это "разбор" данных, а также "Извлечь" его, что верно в некоторой степени, и поэтому XSLT - это правильный инструмент, а не XQuery.
Одна внешняя ссылка, которую я нашел, которая имеет способ XQuery для удаления пространств имен и поэтому возвращает вам "необработанный" XML здесь.
Применение этого кода к вашему 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 объявляет его "в первый раз", когда он сталкивается с пространством имён, используемым им, когда он ходит по этой ветке дерева, что означает, что если есть братья и сестры, которые используют ns, то он будет объявлен несколько раз. Перемещая явное размещение объявления обратно в родительский node, мы можем это исключить.
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;