2016-07-28 30 views
2

Oracle Version 11.2Oracle XMLQuery verdirbt der Namespace

Im Folgenden wird eine abgespeckte Version eines XMLQuery i auf einer XMLType Spalte renne. Wenn ich die Abfrage ausführe, die das gespeicherte XML einfach analysiert und neu erstellt, wird der TSXM-Namespace (, der ungleich dem Standardnamespace ist) geändert. Diese Abfrage tut nichts und könnte leicht umgeschrieben werden, aber die echte (viel größere) Abfrage verwendet die gleiche Methode, deshalb posten wir die Frage in diesem Format. Wenn ich die tsxm Namespace-Definition auf die gleiche sein wie die Standard-Namespace ändern:

xmlns:tsxm="http://schemas.thomson.com/ts/20041221/tsip" 

dann geht das Problem weg, aber in der realen Anwendung ist dies nicht möglich.

Erstellen Sie die Tabelle:

CREATE TABLE XML_DOCUMENT_TMP 
(
    DOCUMENT_ID NUMBER(12)      NOT NULL, 
    XML_DATA  SYS.XMLTYPE      NOT NULL, 
    CREATED_DATE TIMESTAMP(6)     NOT NULL 
); 

einige Daten eingeben:

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> 

‚);

Führen Sie das 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"; 

     let $patsLus := $m/patent/* 

     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); 

Returns:

<patent xmlns="http://schemas.thomson.com/ts/20041221/tsip" xmlns:syspfx_AT="http://schemas.thomson.com/ts/20041221/tsip" syspfx_AT:action="replace" syspfx_AT:cc="CA" syspfx_AT:se="2715340" syspfx_AT:ki="C"><accessions xmlns="http://schemas.thomson.com/ts/20041221/tsip" action="replace"> 
<accession src="wila" type="key">CA-2715340-C</accession> 
<accession src="tscm" type="tscmKey">CA-2715340-C-20150804</accession> 
</accessions> 
<claimed xmlns="http://schemas.thomson.com/ts/20041221/tsip" action="replace"> 
<claimsTsxm lang="en"> 
<syspfx_1:heading xmlns:syspfx_1="http://schemas.thomson.com/ts/20041221/tsxm" syspfx_1:align="left">We Claim:</syspfx_1:heading> 
<claimTsxm no="1" xmlns:syspfx_1="http://schemas.thomson.com/ts/20041221/tsxm" syspfx_1:num="1" type="main">1. power.</claimTsxm> 
</claimsTsxm> 
</claimed> 
</patent> 

Also, die Frage ist, was die tsxm Namespace-Deklaration verursacht zu syspfx_AT und das tsxm Namespacepräfix Xmlns geändert werden: syspfx_1?

Alle Ideen sehr geschätzt.

Antwort

1

Dies scheint zu erwartendes Verhalten, nach My Oracle Support doc ID 2060374.1. Aber nach ein paar Experimenten scheint es, dass das Platzieren des Namespace in Ihrem XPath es verhindert; so:

<patent>{$m/*:patent/@*} 
    { 
    for $i in $m/*:patent/* 
     return $i 
    } 
    </patent>' 

Mit Ihren Originaldaten (in 11.2.0.4) und serialisiert sie formatiert mehr leserlich:

WITH tmpTable AS (
SELECT * FROM XML_DOCUMENT_TMP cm) 
SELECT tt.xml_data , 
XMLSerialize(DOCUMENT 
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"; 

     let $patsLus := $m/patent/* 

     return   
     <patent>{$m/*:patent/@*} 
     { 
     for $i in $m/*:patent/* 
      return $i 
     } 
     </patent>' 
      PASSING tt.xml_data as "m" RETURNING CONTENT) 
AS VARCHAR2(4000) INDENT SIZE = 2) ewXml 
FROM tmpTable tt 
WHERE tt.document_id in (1); 

XML_DATA 
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
NEWXML 
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
<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" tsi 
p: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> 
<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/tsxm" tsxm:align="left">We Claim:</tsxm:heading>                            
     <claimTsxm tsip:no="1" xmlns:tsxm="http://schemas.thomson.com/ts/20041221/tsxm" tsxm:num="1" tsip:type="main">1. power.</claimTsxm>                        
    </claimsTsxm>                                                      
    </claimed>                                                       
</patent>                                                        

Das ist nicht identisch mit Ihrem Original ist aber nicht über den Namespace Korruption nicht mehr. Ob Sie das in Ihrer echten Abfrage tun können, und ob der Platzhalter dafür irgendwelche Probleme verursacht, ist eine andere Sache ...

+0

Alex - Googling "MoS doc ID 2060374.1" gibt nichts zurück, aber das ist mir egal. Ihr Namespace-Platzhalter hat in der echten Abfrage ein Vergnügen bereitet. Vielen dank für Deine Hilfe. –

+0

MoS ist [My Oracle Support] (https://support.oracle.com); Sie benötigen ein Oracle-Konto zum Anmelden und wahrscheinlich eine Support-ID, um dieses Dokument anzuzeigen. Aber es sagt dir nicht viel, außer jemand anderes hatte dieses Problem vorher, und Oracle sagte, dass es kein Problem war ... –

+0

Alex - Ich nehme an, dass die varchar2 (4000) Konvertierung, die du benutzt hast, ist das loswerden eingebettete Namespacedeklarationen in Kinder. In der echten Abfrage wird das nicht funktionieren, weil die 4000 Zeichen zu klein sind. Gibt es einen anderen Weg um dieses Problem zu umgehen? –