1

バージョン 11.2 の Oracle XE を使用しています。

私はそのような種類のXMLを持っています:

<root>
    <x a="a"/>
    <x a="b"/>
    <x a="c"/>
</root>

いいえ、シーケンスから値を取得しbて各要素に属性を追加したいのですが、要素ごとに新しい値を取得する必要があります。x期待される結果は次のとおりです。

<root>
    <x a="a" b="1"/>
    <x a="b" b="2"/>
    <x a="c" b="3"/>
</root>

XML に属性を追加するために使用できることがわかりましたがinsertchildxml、シーケンスからすべての属性に同じ (フリスト) 値を追加していますb。個々の要素ごとにこの関数を呼び出す方法が見つかりませんx

どんな助けにも感謝します。

4

2 に答える 2

2

私は最終的にいくつかの解決策を見つけました。その鍵は XMLTable() 関数を使用することでした。これが私のコードです:

declare
v_inXML xmltype;
  v_tmpXML xmltype;
  v_withIdXML xmltype;
  v_outXML xmltype;
BEGIN   
  v_inXML := XMLType('<root><x a="a"/><x a="b"/><x a="c"/></root>');
  v_withIdXML := XMLType('<root/>'); 
  v_outXML := XMLType('<root/>');

  for c_rec in (
    select *
    from   XMLTable('for $i in /root/x
          return $i'
          passing  v_inXML
          columns x xmltype path '/x'
    )
  )
  loop
    select insertchildxml(c_rec.x,'//x', '@b', pckg_ent_pk_seq.nextval) into v_tmpXML from dual;      
    select insertchildxml(v_withIdXML, '/root', 'x', v_tmpXML) into v_withIdXML from dual;    
  end loop;

  select updatexml(v_outXML, '/root', v_withIdXML) into v_outXML from dual;

  dbms_output.put_line(v_outXML.getClobVal());
END;

結果は次のとおりです。

<root><x a="a" b="92"/><x a="b" b="93"/><x a="c" b="94"/></root>
于 2013-09-13T13:24:11.987 に答える
0

それはさまざまな方法で行うことができます。選択は、ソース データの構築方法、目的の出力形式などによって異なります。

1. XSLT 変換

関数を使用XMLTransform()して属性を追加します。

SQLFiddle test

  with params as (
    select 
      XMLParse( content
        '
        <root>
            <x a="a"/>
            <x a="b"/>
            <x a="c"/>
        </root>                  
        '
      ) as doc_field
    from dual
  )
  select
    XMLTransform( 
      doc_field,
      XMLParse( content
        ' 
        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="/">    
           <root>
           <xsl:for-each select="child::*">
             <xsl:apply-templates></xsl:apply-templates> 
           </xsl:for-each>
           </root>
        </xsl:template>
          <xsl:template match="x">
              <x  a="{@a}" b="{position()}" />
          </xsl:template>
        </xsl:stylesheet>
        '
      )
    )
  from params

2. 単一の XML を返す XQuery

関数 single XMLを使用XMLQuery()すると、基本的に上記と同じ別のバリアントに変換できます。

SQLFiddle test

with params as (
  select 
    XMLParse( content
      '
      <root>
          <x a="a"/>
          <x a="b"/>
          <x a="c"/>
      </root>                  
      '
    ) as doc_field
  from dual
)
select
  XMLQuery( 
    '
      <root>
      {
        for $x at $pos in $doc/root/x
        return <x a="{$x/@a}" b="{$pos}" />
      }
      </root>
    '
    passing doc_field as "doc"
    returning content
  )
from params

3. 行の順序から値を取得する

この方法は、XML をオンザフライで構築する必要があり、構築フェーズでシーケンス属性値を挿入できる場合により適しています。

SQLFiddle test

with params as (
  select 'a' a from dual union all
  select 'b' a from dual union all
  select 'c' a from dual 
)
select
  XMLElement("root",
    XMLAgg(
      XMLElement("x",
        XMLAttributes(
          a as "a",
          rownum as "b"
        )  
      )
    )
  )
from params

最後のメソッドは、関数を使用してレコードに分割する場合、既に作成された XML にも役立ちXMLTable()ます。

于 2013-09-13T10:25:32.210 に答える