Hi.

Please post everythig to run the example in future. You did not provide the table or the directory object.

I ran the following ant it worked fine:

Code:
DROP TABLE zusers;

CREATE TABLE zusers (
  basic_signon  VARCHAR2(400),
  os_signon     VARCHAR2(400),
  first_name    VARCHAR2(400),
  last_name     VARCHAR2(400),
  disp_name     VARCHAR2(400),
  user_email    VARCHAR2(400),
  user_phone    VARCHAR2(400),
  user_class    VARCHAR2(400)
);

CREATE OR REPLACE DIRECTORY log AS 'c:\';
The procedure I ran is basically the same as yours:

Code:
CREATE OR REPLACE PROCEDURE zbis_users_load
AS
   l_bfile         BFILE;
   l_clob          CLOB;
   l_parser        xmlparser.parser;
   l_doc           xmldom.domdocument;
   l_attrs         xmldom.domnamednodemap;
   l_attr          xmldom.domnode;
   l_nl            xmldom.domnodelist;
   l_n             xmldom.domnode;
   l_text          VARCHAR2 (32767);
   l_email         VARCHAR2 (400);
   l_phone         VARCHAR2 (400);
   l_first_name    VARCHAR2 (400);
   l_name          VARCHAR2 (400);
   l_last_name     VARCHAR2 (400);
   l_basic_signon  VARCHAR2 (400);
   l_os_signon     VARCHAR2 (400);
   l_userclass     VARCHAR2 (400);
BEGIN
   l_bfile := BFILENAME ('LOG', 'users.xml');
   --DBMS_OUTPUT.put_line (SQLERRM);
   DBMS_LOB.createtemporary (l_clob, CACHE => FALSE);
   DBMS_LOB.OPEN (l_bfile, DBMS_LOB.lob_readonly);
   DBMS_LOB.loadfromfile (l_clob, l_bfile, DBMS_LOB.getlength (l_bfile), 1,1);
   DBMS_LOB.CLOSE (l_bfile);

   -- make sure implicit date conversions are performed correctly
   DBMS_SESSION.set_nls ('NLS_DATE_FORMAT', '''DD-MON-YYYY''');

   -- Create a parser.
   l_parser := xmlparser.newparser;

   -- Parse the document and create a new DOM document.
   xmlparser.parseclob(l_parser, l_clob);
   l_doc := xmlparser.getdocument(l_parser);

   -- Free resources associated with the Parser now it is no longer needed.
   xmlparser.freeparser (l_parser);

   l_n := xslprocessor.selectsinglenode(xmldom.makenode (l_doc), '/Access/User');
   l_attrs := xmldom.getattributes(l_n);

   FOR cur_attr IN 0 .. xmldom.getlength (l_attrs) - 1
   LOOP
      l_attr := xmldom.ITEM (l_attrs, cur_attr);
      IF xmldom.getnodename (l_attr) = 'email' THEN
         l_email := xmldom.getnodevalue (l_attr);
      END IF;
      IF xmldom.getnodename (l_attr) = 'phone' THEN
         l_phone := xmldom.getnodevalue (l_attr);
      END IF;
      IF xmldom.getnodename (l_attr) = 'first_name' THEN
         l_first_name := xmldom.getnodevalue (l_attr);
      END IF;
      IF xmldom.getnodename (l_attr) = 'name' THEN
         l_name := xmldom.getnodevalue (l_attr);
      END IF;
      IF xmldom.getnodename (l_attr) = 'last_name' THEN
         l_last_name := xmldom.getnodevalue (l_attr);
      END IF;
   END LOOP;

   l_n := xslprocessor.selectsinglenode(xmldom.makenode (l_doc), '/Access/User/BasicSignon');
   l_basic_signon := xmldom.getnodevalue(xmldom.getfirstchild (l_n));

   --DBMS_OUTPUT.put_line(xmldom.getNodeName(l_n) || '=' || xmldom.getNodeValue(xmldom.getFirstChild(l_n)));
   l_n := xslprocessor.selectsinglenode(xmldom.makenode (l_doc), '/Access/User/OSSignon');
   l_os_signon := xmldom.getnodevalue(xmldom.getfirstchild (l_n));

   -- Get a list of all the EMP nodes in the document using the XPATH syntax.
   l_nl := xslprocessor.selectnodes(xmldom.makenode (l_doc), '/Access/User/Userclasses/Userclass');

   -- Loop through the list and create a new record in a tble collection
   -- for each EMP record.
   FOR cur_uc IN 0 .. xmldom.getlength (l_nl) - 1
   LOOP
      l_n     := xmldom.item(l_nl, cur_uc);
      l_attrs := xmldom.getattributes(l_n);
      l_attr  := xmldom.item(l_attrs, 0);
      
	    l_userclass := xmldom.getnodevalue(l_attr);
      DBMS_OUTPUT.put_line('l_basic_signon=' || l_basic_signon);
      DBMS_OUTPUT.put_line('l_os_signon=' || l_os_signon);
      DBMS_OUTPUT.put_line('l_first_name=' || l_first_name);
      DBMS_OUTPUT.put_line('l_last_name=' || l_last_name);
      DBMS_OUTPUT.put_line('l_name=' || l_name);
      DBMS_OUTPUT.put_line('l_email=' || l_email);
      DBMS_OUTPUT.put_line('l_phone=' || l_phone);
      DBMS_OUTPUT.put_line('l_userclass=' || l_userclass);
      INSERT INTO zusers
                  (basic_signon, os_signon, first_name, last_name,
                   disp_name, user_email, user_phone, user_class
                  )
           VALUES (l_basic_signon, l_os_signon, l_first_name, l_last_name,
                   l_name, l_email, l_phone, l_userclass
                  );
   END LOOP;

   -- Free any resources associated with the document now it
   -- is no longer needed.
   xmldom.freedocument (l_doc);
END;
/
The results were:

Code:
SQL> exec zbis_users_load
l_basic_signon=Administrator
l_os_signon=devadmin
l_first_name=
l_last_name=
l_name=Administrator
[email protected]
l_phone=+99 999 999999
l_userclass=Root User Class

PL/SQL procedure successfully completed.

SQL>
I was not able to reproduce your issue. I'm running on 10g. Perhaps this is the difference. I don't have any 8i or 9i instances to dabble with, so if this is the problem I won't be of much use I guess.

Cheers

Tim...