2012-10-22 10 views
7

Oracle SQLとXMLに問題があります。Oracle SQLで未知の名前空間でXMLを解析する

外部システムから適切な形式のXMLデータを集めて解析し、解釈し、いくつかの表を埋め込むことになるでしょう。私はXMLTableを使って解決策を書いた。これは、問題のxml clob列といくつかの監査情報と要素を持つテーブルのビューにレイアウトされている(私はこのようにしたい)。

NAMESPACESが私に悪夢を与えています。私は決してが何であるかを知ることができないので、xmlnamespaces節にそれらを入れることはできません。です。おとぎ話!同じタイプの配信されたアイテムは、異なる時点で異なる名前空間を持つ可能性があります。有限リストはありません。デフォルトのxmlnsは定数でもありません。

私が今までに思いついたベストの解決策は、解析する前にすべての名前空間を消去するregexp_replace(3、正確には)のセットです。しかし、パフォーマンスは巨大な問題です。

確かに賢いものがありますか?

+0

私たちがあなたを助けるためにあなたのコードをお持ちですか? – justderb

+0

Oracleはセキュリティを強化し、外部XMLスキーマURLへの呼び出しをすべて停止します。つまり、DBMS_XMLSCHEMA(登録スキーマ)を使用してすべての有効なスキーマをデータベースに登録する必要があります。しかし、そうでない場合は、すべてのサードパーティ(XML送信)からそれらのリストを取得し、Oracleに登録する必要があります。 – Annjawn

答えて

5

私はこれがかなり古くなっていることを知っていますが、今日はそれを見つけて、名前空間のXMLに対処しようとしたときの痛みを思い出しました。私の解決策は、XSLT変換を使用して名前空間を取り除き、それを単純な古いXMLとして処理することでした。私がこれを行うのに使用した関数は次のとおりです。

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; 
関連する問題