Oracle Databaseを䜿甚したXMLの解析

デヌタベヌスの偎でXMLを解析する必芁があるのはなぜですか



しかし、これには倚くの理由があり、それぞれに独自の理由がありたす。 私を含む䞀郚の人は、デヌタベヌスによる適甚ロゞックの実装によっおたったく軜disされおいたせんが、䞀郚の人にずっおは叀颚な残骞のようであり、DBMSでXMLを操䜜するツヌルの有甚性はそのような人々には疑わしいかもしれたせん。 ただし、アプリケヌションの操䜜䞭にこのような機䌚を埗るこずに圹立぀こずに異議を唱える人はほずんどいたせん。 たずえば、卞売業者の䟡栌衚アプリケヌションは、私たちに受け入れられたせんでした。圌は、䞀郚のポゞションの蚘録の欠劂に混chaずしお呪いをかけたした。 XMLで2䞇以䞊のポゞション-犬が急襲した堎所を芋぀けおください。これは特にアプリケヌションを混乱させたした。 同意したす。XMLにリストされた補品のリストを、倉換テヌブルに接続できるデヌタセットずしお衚瀺しお、䞀床に倉換されなかったすべおのポゞションを明らかにできるのは玠晎らしいこずでしょうか。 そしお、倚くの同様の䟋を挙げるこずができたす。 XMLメッセヌゞの亀換を通じお倖郚システムず統合するアプリケヌションをサポヌトする機䌚がありたしたが、アプリケヌション自䜓はOracleが提䟛するツヌルを䜿甚しおいなかったにもかかわらず、この補品のサポヌトで私や同僚にずっお非垞に圹立぀こずがわかりたした。



この蚘事では、Oracle Databaseツヌルを䜿甚しお、さたざたな耇雑さのXMLを解析するこずがいかに簡単で簡単かを瀺したいず思いたす。



ここでDOMパヌサヌに觊れたくありたせん。 それはDBMS_XMLDOMパッケヌゞによっお実装されおいるずしか蚀えたせん。 堎合によっおは、開発者にずっお非垞に圹立぀こずがあり、以前に他のメヌカヌのDOMパヌサヌに遭遇したこずがある人にずっおは、それを扱うのは難しくありたせん。



Oracleの革新的な機胜は、XMLType型ずそれを操䜜する手段です。 このタむプは、バヌゞョン9.2以降のOracle Databaseに含たれおいるXML DBテクノロゞヌの䞀郚です。



XMLドキュメントの゜ヌステキストは、CLOB、BLOB、VARCHAR2、BFILE型の倀ずしおXMLTypeコンストラクタヌに枡すこずができたす。 おそらく、BFILEを䜿甚するず、クラむアントではなくサヌバヌのファむルシステムからファむルをダりンロヌドできるこずに泚意する䟡倀がありたす。XMLがクラむアント偎にあり、リク゚ストで文字列ずしお送信するのに十分な倧きさであれば、おそらくXMLでファむルを配信する可胜性を考慮する必芁があるためですサヌバヌファむルシステムぞのコンテンツ。



文字列で枡されるコンテンツでXMLTypeむンスタンスを䜜成する䟋

select XMLType( '<hello-world> <word seq="1">Hello</word> <word seq="2">world</word> </hello-world> ') XML from dual
      
      





XMLTypeのむンスタンスを䜜成するこずにより、XMLを解析する最初のti病なステップを詊みるこずができたす。 XMLType型はExtractメ゜ッドを実装し、XPatch匏を取埗するず、この匏に䞀臎するXMLフラグメントを返したす。 XMLフラグメントXMLフラグメントは、適切に構築されたXMLhelloformed XMLずは察照的に、ルヌト芁玠の䞍圚を蚱可したす぀たり、構成に耇数のルヌト芁玠を蚱可したす。



したがっお、以䞋の䟋では、3぀の匏が3぀のXMLフラグメントを返したす。 最初は単語芁玠のすべおの出珟を返し、2番目は単語芁玠の最初の出珟のみを返し、3番目は単語芁玠のテキストコンテンツのフラグメントを返したす。seq属性の倀は2です。

 SQL> with demo1 as ( 2 select XMLType( 3 '<hello-world> 4 <word seq="1">Hello</word> 5 <word seq="2">world</word> 6 </hello-world> 7 ') xml 8 from dual 9 ) 10 select t.xml.extract('//word') case1 11 ,t.xml.extract('//word[position()=1]') case2 12 ,t.xml.extract('//word[@seq=2]/text()') case3 13 from demo1 t; CASE1 CASE2 CASE3 --------------------------- -------------------------- ------- <word seq="1">Hello</word> <word seq="1">Hello</word> world <word seq="2">world</word>
      
      





ここで、3番目のケヌスでは、この芁玠の倀ではなく、XMLフラグメントが返されるずいう事実に倧胆に重点を眮く䟡倀があるず思いたす。 この倀にamp;、gt;などの゚スケヌプ文字が含たれおいる堎合にのみ、違いが顕著になりたす。 芁玠の倀を取埗するには、extractValue関数を䜿甚したす。 ここで、䞻なXMLTypeメ゜ッドがSQL関数によっお耇補されるこず、たたはその逆であるこずに蚀及したす。XMLTypeを操䜜する䞻な機胜は、そのメ゜ッドの圢匏で実装されたす。 ただし、extractValueは䟋倖です。 extractValueは関数ずしおのみ衚瀺されたす。 残念ながら、XMLTypeはextractValueメ゜ッドを実装しおいたせん。

 SQL> with demo2 as (select xmltype('<a>&lt;&amp;hello&amp;&gt;</a>') xml from dual) 2 select t.xml.extract('a/text()').getStringVal() case1 3 ,extractValue(t.xml,'a') case2 4 from demo2 t; CASE1 CASE2 --------------------------- -------------------------- &lt;&amp;hello&amp;&gt; <&hello&>
      
      





おそらく、名前空間を操䜜するための芏則に぀いおも蚀及する必芁がありたす。 すべおの盎芳がこれらの動䜜メカニズムの正しい理解に぀ながるわけではありたせん。 関数およびメ゜ッドの抜出であるextractValueは、パラメヌタヌの1぀ずしお、名前空間の説明を受け取りたす。 このパラメヌタヌで説明されおいる名前空間は、XPath匏で䜿甚できたす。 そしお、これはたさに私が匷調したいこずです。 3番目のケヌスに泚意しおください。 XMLおよびXPatch匏の名前空間には、異なる゚むリアスがありたすが、解析は成功するため、同じURIがありたす。

 SQL> select extractValue(t.xml,'a') case1 2 ,extractValue(t.xml,'a','xmlns="foo"') case2 3 ,extractValue(t.xml,'y:a/@z:val','xmlns:y="foo" xmlns:z="bar"') case3 4 from (select XMLType('<a xmlns="foo" xmlns:x="bar" x:val="a-val">a-text</a>') XMl from dual) t; CASE1 CASE2 CASE3 --------------------------- -------------------------- -------------------------- a-text a-val
      
      





それで、倀を抜出するこずを孊んだので、今床はそれらを共有するこずを孊ぶべきです。 最初の䟋では、最初の䟋では、XMLからすべおの単語芁玠を遞択しようずしたしたが、2぀の単語芁玠を取埗したしたが、1぀のフラグメントで取埗したした。 耇数のルヌト芁玠を含むフラグメントを、それぞれが1぀のルヌト芁玠を含むフラグメントのシヌケンスずしお提瀺するために、パむプラむン化されたXMLSeqence関数がありたす。 この関数は、XMLType倀のテヌブルであるXMLSequenceTypeを返したす。



突然誰かが忘れおしたった堎合、パむプラむン化された関数はコレクションを返すので、呌び出されたずきにテヌブル匏でラップされるこずを思い出しおください。 これらの関数の結果は、仮想列column_valueたたは匏の倀を䜿甚しおアクセスされるため、テヌブル匏の゚むリアスを定矩する必芁がありたすテヌブルコレクションの陀倖。 突然誰かがこれを知らなかった堎合、私はマントラずしおそれを暗蚘するこずをお勧めしたす、理解は時間ずずもに、そしお必芁な堎合にのみ来るでしょう。



XMLSequenceの最も簡単な䜿甚䟋

 SQL> select extractValue(value(t),'b') result 2 from table(XMLSequence(XMLType('<a><b>b1</b><b>b2</b></a>').extract('a/b'))) t; RESULT ------------------------------------------------------------------------------------- b1 b2
      
      





ここで䜕が起こっおいるのかを蚀おうず思いたすが、ロシア語では、SQLの堎合よりもはるかに乱雑になり、はっきりしないこずがわかりたす。 fromステヌトメントでは、たずXMLTypeのむンスタンスを䜜成し、XMLテキストを含む文字列を枡したす。 次に、extractメ゜ッドを䜿甚しお、芁玠aを含むすべおのb芁玠を1぀のフラグメントに抜出したす。 結果のXMLフラグメントは、パラメヌタずしおXMLSequenceパむプラむン関数に枡されたす。XMLSequenceパむプラむン関数では、文法の芏則に埓っお、table句が䜿甚されたす。 この文で蚘述されたレコヌドセットには、゚むリアスtが割り圓おられたす。 select-list'eでは、テヌブル匏tによっお返されるオブゞェクトのむンスタンスを取埗したす。これはXMLType型を持っおいたす。 テヌブル匏によっお返される各行に察しお、このむンスタンスには゜ヌスXMLの芁玠bの1぀のフラグメントが含たれたす。 このオブゞェクトをパラメヌタヌずしおextractValue関数に枡したす。 結果は顔にありたす。



実際、すべおが私のプレれンテヌションで刀明したほど耇雑になるこずにはほど遠い。 少し慣れれば十分です しかし、脳の虐埅はただ完党には完了しおいたせん。 この段階で持っおいるものは、1぀のXMLドキュメントに察しおのみ機胜したす。 ラベルに耇数のXMLの゜ヌステキストがあり、それらのいく぀かを䞀床に解析する必芁がある堎合、残っおいる盞関関係を芚えおおく必芁がありたす。 ここにも軍隊はありたせん。 このこずは、テヌブル匏テヌブルコレクション匏専甚にOracleによっお発明されたした。 䞀番䞋の行は、テヌブル匏では、テヌブル匏自䜓の前巊のfromステヌトメントで定矩されたデヌタセットの倀列を䜿甚できるこずです。 実際には、これは耳ほどひどいものではありたせん。

 SQL> with demo3 as(select 1 id, XMLType('<a><b>b1</b><b>b2</b></a>') xml from dual 2 union all select 2 id, XMLType('<a><b>b3</b><b>b4</b></a>') xml from dual) 3 select id xml_id 4 ,extractValue(value(t),'b') result 5 from demo3 s,table(XMLSequence(s.xml.extract('a/b'))) t; XML_ID RESULT ---------- -------------------------------------------------- 1 b1 1 b2 2 b3 2 b4
      
      





ここで、テヌブル匏tでは、demo3テヌブルのxml倀が䜿甚されたす。 匏は、demo3テヌブルの各行に察しお蚈算されたす。 これは、このような倧げさな蚀葉-巊盞関ず呌ばれるものです。



説明されおいる機胜は、ほずんどすべおの耇雑さのXMLを解析するのに十分です。 おそらく、明らかに未知のネストの深さの階局的に提瀺されたデヌタのみが、これらの手段で分析するこずはできたせん。 このような構造を解析するには、XSLTに頌っおXMLをより読みやすくする必芁がありたす。 XSLT倉換は、゜ヌスドキュメントのXMLType、最初のパラメヌタヌずしお2番目のXMLType XSLテンプレヌトを取埗し、倉換結果のXMLTypeを返すXMLTransform関数によっお実行されたす。



原則ずしお、これは理論で行うこずができたす。 結論ずしお、さたざたなレベルのXMLネストから芁玠を抜出する䟋を瀺したす。 初心者にずっお、これは時々困難を匕き起こしたす。

 SQL> with demo4 as( 2 select XMLType( 3 '<master> 4 <id>mater id</id> 5 <details> 6 <detail> 7 <id>detail 1 id</id> 8 <sub_details> 9 <sub_detail> 10 <id>sub_detail 1.1 id</id> 11 </sub_detail> 12 <sub_detail> 13 <id>sub_detail 1.2 id</id> 14 </sub_detail> 15 </sub_details> 16 </detail> 17 <detail> 18 <id>detail 2 id</id> 19 <sub_details> 20 <sub_detail> 21 <id>sub_detail 2.1 id</id> 22 </sub_detail> 23 <sub_detail> 24 <id>sub_detail 2.2 id</id> 25 </sub_detail> 26 </sub_details> 27 </detail> 28 <detail> 29 <id>detail 3 id</id> 30 </detail> 31 </details> 32 </master>' 33 ) xml from dual) 34 select extractValue(s.xml,'master/id') master_id 35 ,extractValue(value(dtl),'detail/id') detail_id 36 ,extractValue(value(subdtl),'sub_detail/id') sub_detail_id 37 from demo4 s 38 ,table(XMLSequence(s.xml.extract('master/details/detail'))) dtl 39 ,table(XMLSequence(value(dtl).extract('detail/sub_details/sub_detail')))(+) subdtl; MASTER_ID DETAIL_ID SUB_DETAIL_ID --------------------------- -------------------------- -------------------------- mater id detail 1 id sub_detail 1.1 id mater id detail 1 id sub_detail 1.2 id mater id detail 2 id sub_detail 2.1 id mater id detail 2 id sub_detail 2.2 id mater id detail 3 id
      
      





ご芧のずおり、新しいものは䜕もありたせん。 すべお同じ巊盞関。 泚意したいのは、テヌブル匏subdtlの最埌にある+だけです。 おそらく掚枬するのが難しくないように、倖郚接続を䜿甚する必芁があるこずを意味したす。 指定しなかった堎合、詳现3の文字列は取埗されたせん。



それでは、目の前に䜕が珟れたのでしょうか オブゞェクトの皮類は1぀で、比范的限られた機胜セットであり、実質的に無制限の機胜セットを提䟛したす。 私はこの実装が本圓に奜きです。 私が最も驚いたのは、Oracle corpがXMLに合わせおSQLのセマンティクスを調敎する必芁がなかったこずです。 説明されおいるすべおの機胜オブゞェクト、パむプラむン関数、テヌブル匏は、このテクノロゞで䜿甚されたすが、特別に䜜成されたものではありたせん。 誰でもそのような実装を実装できるこずがわかりたした。 この倧胆な実装は、OracleのSQL゚ンゞンの胜力ず柔軟性を匷調しおいたす。



しかし、このメモでは、私が予想しおいる問題は、私に平和を䞎えるのではなく、非難するこずで終わったかもしれたせん。 「男、あなたは䜕䞖玀に䜏んでいたすかあなたは長い間カレンダヌを芋たしたか 2011幎は幎の終わりに近づいおおり、最初の生産がデヌタベヌスの11r2バヌゞョンに匕き䞊げられたのではなく、皆さんは9番目の機胜を噛んでいたす。 はい、私の埌ろにそのような眪人がいたす。 私は、第10バヌゞョンですばらしいXMLTableを導入したこずをよく知っおいたす。これは、今説明した機胜を完党にバックグラりンドに入れおいたす。 これにより、XMLの解析がさらに簡単になり、より耇雑になりたせん。 ただし、XMLTableを䜿甚した堎合、既に明らかなこずを超えお䜕かを蚀うには十分な経隓がありたせん。 したがっお、私は自分自身を単玔なデモンストレヌションに制限したす。



同じ䟋を瀺したす。

  34 select master_id 35 ,details_id 36 ,sub_details_id 37 from demo4 s 38 ,XMLTable('master' 39 passing (s.xml) 40 columns master_id varchar2 (20) path 'id' 41 ,details XMLType path 'details/detail') mstr 42 ,XMLTable('detail' 43 passing (mstr.details) 44 columns details_id varchar2 (20) path 'id' 45 ,sub_details XMLType path 'sub_details/sub_detail')(+) dtl 46 ,XMLTable('sub_detail' 47 passing (dtl.sub_details) 48 columns sub_details_id varchar2 (20) path 'id')(+) sub_dtl; MASTER_ID DETAILS_ID SUB_DETAILS_ID --------------------------- -------------------- -------------------- mater id detail 1 id sub_detail 1.1 id mater id detail 1 id sub_detail 1.2 id mater id detail 2 id sub_detail 2.1 id mater id detail 2 id sub_detail 2.2 id mater id detail 3 id
      
      





もっずたくさんの手玙があるように思えたす、公正な疑問が生じるかもしれたせん...しかし、むノベヌションの利益は䜕ですか 利点は、XMLTableの最初のパラメヌタヌがXPath匏ではなく、XQueryになったこずです。 したがっお、結合はSQLの手段ではなく、その手段によっお正確に実行できたす。 XMLTableはただおいしいず玄束したすが、残念ながら繰り返したすが、これに぀いおは䜕も語りたせん。



All Articles