dbuser
dbuser

Reputation: 13

XMLType pl/sql add child

I have problem with correct adding childs from pl/sql into xml structure like as below.

  <DATA>
  <CHILDRENS>
    <CHILDRENS_DEF lname="smith">
      <CHILD_KOL no="1" name="Id" desc="Id" typ="NUMBER"/>
      <CHILD_KOL no="2" name="Fname" desc="Fname" typ="VARCHAR2"/>
    </CHILDRENS_DEF>
    <CHILDRENS_DATA>
      <CHILD_DATA no="1">
        <CHILD_COL_VALUE no="1" name="Id">1</CHILD_COL_VALUE>
        <CHILD_COL_VALUE no="2" name="Fname">Christopher</CHILD_COL_VALUE>
      </CHILD_DATA>
      <CHILD_DATA no="2">
        <CHILD_COL_VALUE no="1" name="Id">1</CHILD_COL_VALUE>
        <CHILD_COL_VALUE no="2" name="Fname">Alice</CHILD_COL_VALUE>
      </CHILD_DATA>
      <CHILD_DATA no="3">
        <CHILD_COL_VALUE no="1" name="Id">1</CHILD_COL_VALUE>
        <CHILD_COL_VALUE no="2" name="Fname">John</CHILD_COL_VALUE>
      </CHILD_DATA>
    </CHILDRENS_DATA>
  </CHILDRENS>
  <CHILDRENS>
    <CHILDRENS_DEF lname="mushroom">
      <CHILD_KOL no="1" name="Id" desc="Id" typ="NUMBER"/>
      <CHILD_KOL no="2" name="Fname" desc="Fname" typ="VARCHAR2"/>
    </CHILDRENS_DEF>
    <CHILDRENS_DATA>
      <CHILD_DATA no="1">
        <CHILD_COL_VALUE no="1" name="Id">1</CHILD_COL_VALUE>
        <CHILD_COL_VALUE no="2" name="Fname">Arthur</CHILD_COL_VALUE>
      </CHILD_DATA>
    </CHILDRENS_DATA>
  </CHILDRENS>
</DATA>

I want to add child to CHILDRENS where CHILDRENS_DEF = lname=mushroom. When I do something like that:

UPDATE xml_childrens
SET  CLOBXMLCOL = INSERTCHILDXML(CLOBXMLCOL, 'DATA/CHILDRENS','CHILD_DATA', 
                XMLType('<CHILD_DATA no="2">
                            <CHILD_COL_VALUE no="1" name="Id">2</CHILD_COL_VALUE>
                            <CHILD_COL_VALUE no="2" name="Fname">Adele</CHILD_COL_VALUE>
                         </CHILD_DATA>'))

I add new child for all families. How I can add CHILD_DATA only for lname=mushroom. Question no 2. How can I count CHILD_DATA for family?

Upvotes: 1

Views: 3813

Answers (1)

Justin Cave
Justin Cave

Reputation: 231661

Set up the table and insert the data (not that I assume your actual data ends with an </DATA> tag so that it's valid XML

SQL> create table xml_children (
  2    xml_data xmltype
  3  );

Table created.


SQL> ed
Wrote file afiedt.buf

  1  insert into xml_children
  2   values( '<DATA>
  3    <CHILDRENS>
  4      <CHILDRENS_DEF lname="smith">
  5        <CHILD_KOL no="1" name="Id" desc="Id" typ="NUMBER"/>
  6        <CHILD_KOL no="2" name="Fname" desc="Fname" typ="VARCHAR2"/>
  7      </CHILDRENS_DEF>
  8      <CHILDRENS_DATA>
  9        <CHILD_DATA no="1">
 10          <CHILD_COL_VALUE no="1" name="Id">1</CHILD_COL_VALUE>
 11          <CHILD_COL_VALUE no="2" name="Fname">Christopher</CHILD_COL_VALUE>
 12        </CHILD_DATA>
 13        <CHILD_DATA no="2">
 14          <CHILD_COL_VALUE no="1" name="Id">1</CHILD_COL_VALUE>
 15          <CHILD_COL_VALUE no="2" name="Fname">Alice</CHILD_COL_VALUE>
 16        </CHILD_DATA>
 17        <CHILD_DATA no="3">
 18          <CHILD_COL_VALUE no="1" name="Id">1</CHILD_COL_VALUE>
 19          <CHILD_COL_VALUE no="2" name="Fname">John</CHILD_COL_VALUE>
 20        </CHILD_DATA>
 21      </CHILDRENS_DATA>
 22    </CHILDRENS>
 23    <CHILDRENS>
 24      <CHILDRENS_DEF lname="mushroom">
 25        <CHILD_KOL no="1" name="Id" desc="Id" typ="NUMBER"/>
 26        <CHILD_KOL no="2" name="Fname" desc="Fname" typ="VARCHAR2"/>
 27      </CHILDRENS_DEF>
 28      <CHILDRENS_DATA>
 29        <CHILD_DATA no="1">
 30          <CHILD_COL_VALUE no="1" name="Id">1</CHILD_COL_VALUE>
 31          <CHILD_COL_VALUE no="2" name="Fname">Arthur</CHILD_COL_VALUE>
 32        </CHILD_DATA>
 33      </CHILDRENS_DATA>
 34    </CHILDRENS>
 35* </DATA>' )
SQL> /

You can use a following-sibling in your XPath (though it would be much more logical to change the definition of your XML)

SQL> ed
Wrote file afiedt.buf

  1  update xml_children
  2     set xml_data = InsertChildXML( xml_data,
  3                                    '/DATA/CHILDRENS/CHILDRENS_DEF[@lname="mushroom"]/following-sibling::*',
  4                                    'CHILD_DATA',
  5                                    XMLType('<CHILD_DATA no="2">
  6                              <CHILD_COL_VALUE no="1" name="Id">2</CHILD_COL_VALUE>
  7                              <CHILD_COL_VALUE no="2" name="Fname">Adele</CHILD_COL_VALUE>
  8*                          </CHILD_DATA>'))
SQL> /

1 row updated.

SQL> select * from xml_children;

XML_DATA
--------------------------------------------------------------------------------
<DATA>
  <CHILDRENS>
    <CHILDRENS_DEF lname="smith">
      <CHILD_KOL no="1" name="Id" desc="Id" typ="NUMBER"/>
      <CHILD_KOL no="2" name="Fname" desc="Fname" typ="VARCHAR2"/>
    </CHILDRENS_DEF>
    <CHILDRENS_DATA>
      <CHILD_DATA no="1">
        <CHILD_COL_VALUE no="1" name="Id">1</CHILD_COL_VALUE>
        <CHILD_COL_VALUE no="2" name="Fname">Christopher</CHILD_COL_VALUE>
      </CHILD_DATA>
      <CHILD_DATA no="2">
        <CHILD_COL_VALUE no="1" name="Id">1</CHILD_COL_VALUE>
        <CHILD_COL_VALUE no="2" name="Fname">Alice</CHILD_COL_VALUE>
      </CHILD_DATA>
      <CHILD_DATA no="3">
        <CHILD_COL_VALUE no="1" name="Id">1</CHILD_COL_VALUE>
        <CHILD_COL_VALUE no="2" name="Fname">John</CHILD_COL_VALUE>
      </CHILD_DATA>
    </CHILDRENS_DATA>
  </CHILDRENS>
  <CHILDRENS>
    <CHILDRENS_DEF lname="mushroom">
      <CHILD_KOL no="1" name="Id" desc="Id" typ="NUMBER"/>
      <CHILD_KOL no="2" name="Fname" desc="Fname" typ="VARCHAR2"/>
    </CHILDRENS_DEF>
    <CHILDRENS_DATA>
      <CHILD_DATA no="1">
        <CHILD_COL_VALUE no="1" name="Id">1</CHILD_COL_VALUE>
        <CHILD_COL_VALUE no="2" name="Fname">Arthur</CHILD_COL_VALUE>
      </CHILD_DATA>
      <CHILD_DATA no="2">
        <CHILD_COL_VALUE no="1" name="Id">2</CHILD_COL_VALUE>
        <CHILD_COL_VALUE no="2" name="Fname">Adele</CHILD_COL_VALUE>
      </CHILD_DATA>
    </CHILDRENS_DATA>
  </CHILDRENS>
</DATA>
1 row created.

Upvotes: 1

Related Questions