2012-10-22 13 views
7

Ho problemi con Oracle SQL e XML.Analisi di XML con spazi dei nomi sconosciuti in Oracle SQL

Riceverò un sacco di clob di dati XML ben formati da un sistema esterno per analizzare, interpretare e riempire alcune tabelle con. Ho scritto una soluzione usando XMLTable, che è disposto in una vista sulla tabella con la colonna clob xml in questione e alcune informazioni di controllo e roba (mi piacerebbe tenerlo in questo modo).

NAMESPACES mi stanno dando gli incubi. Apparentemente non posso metterli nella clausola xmlnamespaces, perché non posso mai sapere che cosa saranno i. Assurdo! Gli articoli consegnati dello stesso tipo possono avere spazi dei nomi diversi in momenti diversi. Non c'è una lista finita. Neanche xmlns di default è costante.

La migliore soluzione di lavoro che ho escogitato finora è un insieme di regexp_replace (3, per la precisione), che cancella tutti gli spazi dei nomi prima di analizzare. Ma le prestazioni sono un problema colossale.

Sicuramente c'è qualcosa di intelligente che mi manca?

+0

Hai il tuo codice in modo che possiamo aiutarti meglio? – justderb

+0

Oracle applica sicurezza e interrompe qualsiasi chiamata a URL di schema XML esterni, questo significa che tutti gli schemi validi devono essere registrati nel database utilizzando 'DBMS_XMLSCHEMA (schema di registro)', molti schemi sono già registrati nel DB. Tuttavia, se non lo sono, devi ottenere un elenco di questi da tutte le terze parti (invio di XML) e registrarli in Oracle. – Annjawn

risposta

5

So che questo è piuttosto vecchio, ma l'ho notato oggi e ho ricordato il dolore che ho provato nel tentativo di gestire l'XML dei nomi. La mia soluzione era quella di rimuovere gli spazi dei nomi con una trasformazione XSLT e processarla come un semplice vecchio XML. La funzione che ho usato per fare questo è:

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; 
Problemi correlati