XDOM API in UniVerse

[Origin]: https://stackoverflow.com/questions/1727776/xdom-api-in-universe

I am building an xml parser and constructor using the XDOM functions in UniVerse 10.1.0. Things are going fine until I get to use the XDOMAddChild function. I can add single elements fine using the handles but I get an error when adding a tree. The manuals indicate adding a tree is fine.

XDOMAddChild function


XDOMAddChild(xmlHandle, xpathString, nsMap, nodeHandle, dupFlag)


The XDOMAddChild function finds the xpathString in the context xmlHandle in the DOM structure and inserts a node nodeHandle as the last child of the found node. If the inserted node type is XDOM.ATTR.NODE, this node is inserted as an attribute.


The following table describes each parameter of the syntax. Parameter Description

xmlHandle The handle to the context. [IN] xpathString Relative or absolute Xpath string. [IN] nsMap The map of namespaces which resolve the prefixes in the xpath string. Format is “xmlns=default_url xmlns:prefix1=prefix1_url xmlns:prefix2=prefix2_url”

For example: “xmlns=http://myproject.mycompany.com xmlns:a_prefix=a.mycompany.com” [IN]

nodeHandle Handle to a DOM subtree. If nodeHandle points to a DOM document, all of its children are inserted, in the same order. [IN]

dupFlag XDOM.DUP: Clones nodeHandle, and inserts the duplicate node. XDOM.NODUP: Inserts the original node. The subtree is also removed from its original location. [IN]

I accept the XDOM faults and flaws (particularly with building namespace prefixes) and an willing to work with them, But this one may be a show stopper with the current logic I am using. This is some test code:

$INCLUDE UNIVERSE.INCLUDE XML.H                                           
DATA.REQ = '<logonResponse></logonResponse>'
TEST.CHILD = '<logon>HELP</logon>'
NSMAP = ''
ERR$ = XDOMOpen(DATA.REQ, XML.FROM.STRING, DOM$H)                
  Status = XMLGetError(ERR$,errMsg)
  PRINT ERR$:',':errMsg 
  Status = XMLGetError(ERR$,errMsg)
  PRINT ERR$:',':errMsg
ERR$ = XDOMLocate(DOM$H,'//logonResponse',NSMAP,NOD$H)                                   
  Status = XMLGetError(ERR$,errMsg)
  PRINT ERR$:',':errMsg
  Status = XMLGetError(ERR$,errMsg)
  PRINT ERR$:',':errMsg

I get this back….

1004,A DOM exception occured in function XDOMAddChild, DOM Exception code: 4

If I use XDOMCreateNode to create the TEST.CHILD element, the XDOMAddChild works fine. The only difference I can prove ids that the inserted node hanlde is different between teh 2 examples. The one that works the nodehandle is XDOM.ELEMENT.NODE (Type 1) and the one that fails in XDOM.DOC.NODE (Type 9).

Not sure where to go from here. Any code snippets, links, pointers; greatly appreciated


An XML Document is a different kind of beast than an XML Element. A document must contain one, and only one element: the document root, which contains the other elements. It’s can’t directly contain attribute or text nodes. It can contain DTDs, processing instructions, and a declaration, all of which are forbidden for an element to contain. An element can contain nodes; either text, attributes or other elements. An element can’t contain a document.

You answered your own question here:

If I use XDOMCreateNode to create the TEST.CHILD element, the XDOMAddChild works fine. The only difference I can prove ids that the inserted node hanlde is different between teh 2 examples. The one that works the nodehandle is XDOM.ELEMENT.NODE (Type 1) and the one that fails in XDOM.DOC.NODE (Type 9).

Don’t use XDOMOpen, use XDOMCreateNode OR XDOMLocate. You need an element, attribute or text node. A document won’t work.


I actually made a small blog post regarding U2 XDom errors just before Christmas.

I assume UniVerse and UniData use the same XDOM parsers, so you can should be able to work out what that error refers to from the Xalan documentation.

In this case, Error 4 refers to ‘WRONG_DOCUMENT_ERR’

Hope it helps somewhat…



The crux of my problem was that I was confused about the “Document” type as opposed to the “element” type.

eg: You can only use XDOMLocate on the “Document” Type Node. I was trying to use this function on a “element” Type node. The code below will no work because the 2nd Locate is performed on an “element” Type node.

  XMLDOC = <rootNode><nodeItem><data>aaa</data></nodeItem><nodeItem><data>bbb</data></nodeItem></rootNode>
  ERR$ = XDOMLocate(DOM$H,'//rootNode','',NOD$H)
  ERR$ = XDOMLocate(SUBNOD$H,'//nodeItem/data','',DATA$H)

DATA$VALUE will not be extracted to “bbb”. This is how to do it..

  ERR$ = XDOMLocate(DOM$H,'//rootNode/nodeItem[2]/data','',DATA$H)
All nodes are not created equal.

unibasic select woes

[Origin]: http://u2-universe-unidata.1073795.n5.nabble.com/unibasic-select-woes-td15195i20.html

RE: unibasic select woes

Morelli, David W.
6 posts
Thank you.  The “‘word’…” format is the answer to a question that had
me banging my head yesterday.

David Morelli, UIS/Datatel Team

—–Original Message—–
From: [hidden email]
[mailto:[hidden email]] On Behalf Of Andre Meij
Sent: Wednesday, May 30, 2007 5:10 PM
To: [hidden email]
Subject: RE: [U2] unibasic select woes


Actually the following in saver:


(note the extra ‘ around the text) there are a few alphanumeric
characters that are interpreted by SELECT and it will show you weird
results when you are not expecting that.



—–Original Message—–
From: [hidden email]
[mailto:[hidden email]] On Behalf Of Greg Schraiber
Sent: maandag 30 april 2007 11:12
To: [hidden email]; [hidden email]
Subject: RE: [U2] unibasic select woes

Dave, Wyatt  & Karen,

Thank you so much for the tips!
Works like a charm!

Thanks again,

At 12:45 PM 5/30/2007, Dave Davis wrote:

>If you are currently in ECLTYPE p, you can put the word “SELECT” in
>lowercase to evaluate using the “u” parser.
>—–Original Message—–
>From: [hidden email]
>[mailto:[hidden email]] On Behalf Of Greg Schraiber
>Sent: Wednesday, May 30, 2007 1:28 PM
>To: [hidden email]
>Subject: [U2] unibasic select woes
>How does one select alpha-numeric data from a unidata datafile using
>SELECT when the case of the text is not known?
>I have tried things like:
>but all I get is a syntax error.
>Can someone tell me which function(s) can be used to facilitate this
>type of search?
>Any help is greatly appreciated!
>Thank you,

Stop RF Gun Wireless disconnects

[From]: http://www.precisonline.com/forum/index.php/topic,245.0.html

We had a problem with our RF barcode scanners that we use in our warehouse for inventory: every once in a while, they’d lose the connection to the host.  Sometimes when the connection got dropped, they’d be in the middle of picking an order, and the dropped connection left the order in a messy state.

In order to mitigate this problem, we use screen http://www.manpagez.com/man/1/screen/ (AIX RPMs here: http://www.oss4aix.org/download/RPMS/screen/) to abstract the session on the RF device — if the connection drops, the same user can just log back in and resume the screen session.  One caveat — screen is for all intents and purposes a VT100 terminal emulator, so you have to make sure that whatever you’re connecting to (in our case Prelude) is expecting VT100, and the device you’re using is expecting the same.

To automate this, part of the login script for our RF gun users is:

export TERM=vt100

if screen -ls | grep "No Sockets found" &gt; /dev/null 2&gt;&amp;1
  screen -s /usr/local/bin/prelude.login
  exit 0
  SCREEN=`screen -ls | grep -v "screen" | awk '{print $1}'`
  echo "You are already logged on."
  echo "What do you want to do:"
  echo "1 - Resume Previous Session"
  echo "2 - Start a New Session"
  while [ ! "$yn" = "1" ] &amp;&amp; [ ! "$yn" = "2" ]
    echo "Please enter 1 or 2."
    read yn
  if [ "$yn" = "1" ]
    screen -D -R $SCREEN
  if [ "$yn" = "2" ]
    screen -s /usr/local/bin/prelude.login

exit 0

Killing Unidata session (softly with STOPUDT)

[From]: http://ecolleague.blogspot.ca/2015/08/killing-unidata-session-softly-with.html

Killing Unidata session (softly with STOPUDT)

A while back when Colleague UI was first introduced, users started to X’ing out of the web-browser to close the session instead of using the logout button. That resulted in many runaways processes that used up the small license pool we had. I learned to kill those sessions through the terminal as following:

Open Colleague Desktop UI terminal:

LISTUSER: this lists all active sessions

LISTUSER | findusername“: this finds a particular user’s active sessions with “username”

Kill the session by:

STOPUDT usrnbr(user number): kill the session using the user’s number, it’s the number on the second column after using LISTUSER

* Note: insert a bang (“!”) in front of LISTUSER or STOPUDT to use admin right if the commands don’t work

You can use LISTUSER to check to see if your process is still running or the screen has frozen. Many times I waited for a process for so long just to find out the session was disconnected.

UniData Development Notes

                                                                           UniData Development Notes
U2 Best Practice
Subroutine U2Central(FunctionToCall,Action,InData,OutData,ErrText)



…could lookup up Function to see what interface it has then either

Call @FunctionToCall(Action,InData,OutData,ErrText)

Call @FunctionToCall(InData,OutData,ErrText)

Call @FunctionToCall(InData,OutData)





Infoflo Development Standard
Before make any changes in Infoflo, following the standard procedures below,
  1. Use COMPARE command to check if the BP Program or Process in DEV.DATA that is about to be changed is identical with the version in live account, i.e. ACCT.DATA
  2. If it is identical, then make a copy of the program in the format as ProgramName.JUNTAN.SAVE.mmddyyyy, otherwise report to Gervais for the inconsistence.
  3. Check if there exist previous copies by other programmer and do the purging accordingly. (in case of deleting, make sure the object code, catalog and voc entry are deleted also. Do not use DELETE directly to delete a program but using SELECT -> OS.ED instead, also never use DELETE.FILE because it will caused the entire file entry, namely, the directory to be deleted. Use DELETE.CATALOG to remove a catalog, this will also delete the corresponding VOC entry, and it might require more than one time in order to delete the local catalog and the global catalog)
  4. In case of flicking BP program in SRC, make sure to use the COMPARE command to check it with the version in live after the flicking is done and recompile the program as well by using OS.SE -> F8 or OS.AE with option FIBCDF
  5. As a general rule, rollouts into production on Monday & Tuesday after 4pm (EST).
  6. When a new file or a new field is introduced, make sure to create or update the corresponding EQU_XXX file by using IPEX.EQUATES tool and inform windows development team as well.
  7. Make sure to clear the test code during development time before requesting to do the rollout!!!
  8. Never ever try to use OS.ED or OS.SE in ACCT.DATA and PREP.DATA account!!!
  9. Sometimes it might need to recompile BP program once it is rolled into PREP.DATA and ACCT.DATA.
  10. In paragraph, when we do a read file, the system will automatically open the file, so no open file command is needed (refer to IECP4010.9 as an example)
  11. In paragraph, it is not allowed to explicitly use ; as string delimiter since it is used in the object source code of the paragraph. An alternative way of overcoming this is to use CHAR(59) to indicate an implicitly using of ;.
Infoflo System Tools
ED Line Editor:
  • FI (or SV or SAVE) -> Save the file
  • FIB -> Save the file and compile
  • FIBCDF -> Save the file, compile and force to generate local catalog in case it already exists
  • FD -> Delete the file
  • EV -> Multi-Value drill down (@VM)
  • ESV -> Multi-Sub-Value drill down (@SVM)
Infoflo How to FAQ?
How to send the output of a UniData command to the printer directly?
  • Any UniData Command + Space + LPTP (ex. SORT BP = “xxxxxx” LPTP)
How to kill a locked Infoflo user session?
  • Login with username TECHSUP, password TECHFISH
  • Following the menu to kill the locked user session(s)
How to print a purchase report in dev environment?
  • PUR4000 to get a purchase order number along with the buyer code
  • SYS3005 -> BYR to get the buyer’s number
  • SYS9030 -> PO + Buyer # to reset the associated printer (or change to another printer) from option HS to HP
  • Call the process to print the report
How to sequentially modify records in a file?
  • Use SELECT or SSELECT to get the key list of a file
  • Use SAVE.LIST to save the active list (list buffer #0)
  • Use GET.LIST to retrieve the key list of a file
  • Use ESEARCH filename to locate certain string in the records of the file
  • Use SE filename to sequentially modify the records (hit ESC to go to the next record)
How to set focus for a field on a screen?
  • Ex. P:(@RTN.FLAG = “{W_DIRECTORY}”) -> set focus point to return  or EXIT {FILED NAME}
How to copy records from one file to another file? (Source file and destination file should have the same structure)
  • Use SELECT statement to save the desired records into the current list
  • Use COPY + SourceFileName
  • When prompted as TO: for destination file, enter ( + destination file name (no space in between)
  • Enter Y when ask if get id’s from select list
How to regenerating driver for a screen?
  • Process name – Main screen process
  • Options – SD
    • S Force Screen Definition to be rebuilt
    • D Force Driver to be rebuilt
    • Transfer Drivers to DOS
    • Quiet mode (no progress messages)
How to generate source code for screen?
  • TM -> Generate Source Code -> Enter the process name of the screen
  • The generated source code will be stored in IIPROGS
SB+ and UniData Miscellaneous
SB+ Reference:
  • GC – Generate Source Code (/GC can be used on TCL to compile paragraph or basic program)
  • MP – Modify Process
  • FD – Field Definition
  • SD – Screen Definition
  • MD – Menu Definition
  • PD.P – Paragraph Definition
  • SBX – Tree view for menu under GUI mode
  • DEBUG – View SB+ common variables
  • COMMON – It will show an interface for common variables like @KEY, @RECORD, @WORK, etc…
  • QUICK – Use this to see full description of project that has been rolled into production already.
  • EE – View the result of any valid SB+ expression
  • EEGC – Prompts for a standard SB+ expression and displays the BASIC code generated by SB+.
  • \ – Clears a field (make it null)
  • / – Allows you to call a process (if permitted by your security level), e.g. /WHO
  • /n – Moves the cursor directly to field n, in the tab order specified for the screen.
  • /n.m – Moves the cursor directly to a value m within a multi-valued field n on a screen, e.g. /0.999 jumps to the last value in the window plus one, with the cursor positioned in the controlling multi-valued field.
  • KEYS display the list of current edit keys. The keys displayed depend on the terminal definition currently in use for the terminal.
  • USER.FLAGS defines the screen refresh mode.
  • Length Of Field – If you wish to prevent data extending beyond the nominated field length, or you want an auto-carriage return when the cursor has reached the field length limit, enter the length as a negative number.
  • Expressions as conversion codes, e.g. (IF (@VALUE > CREDIT.LIMIT,BLINK.ON :@VALUE’MD2’ :BLINK.OFF,@VALUE’MD2’)). BLINK.ON is equated to @TERM.DEFN<3,4> and BLINK.OFF is equated to @TERM.DEFN<4,4>
  • Online Help Document for sub-screen – P:(@PARMS(30)<2,1>=”SYSI9105.1S”) -> put this code in Proc Before Screen under Screen Parameters (F6)  (Has to set the process name back as the main process name i.e SOP6100)
  • Enable Online Help option: F10 Action ACTION -> A10 [H]elp M:SYSHELP2
  • In field definition, if set the length of field to -1, the carriage return will be inserted after the input automatically.
  • KEY”G0*1” – search key with delimiter *, skip 0 and return 1
  • In paragraph, when use READL to lock a record after read, a WRITE or WRITEV command will not automatically release the record lock as it will do in BP program, so we need to explicitly user RELEASE command to release the lock at the end.
  • Convert value from lower case to uppercase in paragraph. (@VALUE = OCONV(@VALUE,’MCU’))
  • @OTHER(17) # ‘’ -> program is run under batch mode, otherwise it is run under TCL.
  • On field definition Screen (F5), press F6 to bring Additional Field Parameter and set the length as desired to override the actual length of the field defined in file dictionary.
  • Use common variable GUI to determine the current terminal mode, i.e. 1 -> GUI Mode and 0 -> CHAR Mode
SB+ Paragraph Syntax:
  • @VALUE = REPL(” “,””,@VALUE) (Trim extra space in the string)
  • EXEC ‘SYS0061,7583\’:SYSTBL_KEY
  • EXEC “DIALOG,xxx” or DISP 4, “xxx”
  • FIELD.ID = @LINE<1,18> (favorite global equates, SB+ Solutions @ page 8-26)
UniBasic Program:
  • Dynamic array xxx<-1> assign the next value in the array and separated by @FM
  • Check record lock and indicate the user who is currently locking the record.
      CALL IILK(KEY,SOHDR,ILC,FLG)                                 
WHILE FLG DO                                                              
      L_USER_LOCK_REC = GETUSERNAME(STATUS())                                
      CALL SB.PROCESS(‘SYS0061,IP2292\’:KEY:@VM:L_USER_LOCK_REC:’\\7′)
How to execute BP command in paragraph and put result in selection list?
  2. L_STMT = ‘S:SSELECT SYSTBL WITH @ID = “I242*]”‘                              
How to execute UniQuey command in paragraph?
  • EXEC ‘>:UniQuery_Command’
    1. sub-screen with read field should have its screen parameters “Write Record (Y/N)” set to ‘N’, otherwise, the system will treat it as a main input screen and the feature for sharing common variables such as @KEY, @WORK, @RECORD, etc. between the main screen and sub-screen will not be applicable anymore. However, if the sub-screen does not have any read field, then the screen parameters “Write Record (Y/N)” should be set to null (no value) for sharing common variables.
    2. Once you create a select list, any subsequent select statement acts against that list. You must delete or deactivate the active select list before retrieving IDs based on completely new criteria.
    3. Trick to synchronize @CNT between parent screen and sub-screen:
      1. Store @CNT on parent screen to work variable @WORK<300> for example.
      2. Set value on Proc Before Screen slot of Screen Parameters to @3 (up arrow), this will initialize @CNT for the multivalue field.
      3. Set @CNT @WORK<300> – 1 and @REFRESH=-2
UniData Reference:
  • LIST BP WITH @ID = “xxx””yyy” (ex. Select all records in file BP that match either “xxx” or “yyy”)
  • ESEARCH.DICT COMO ALL -> Searching for certain string appears in all DICT
  • MATREAD – Reads record and parses the fields into successive elements of a matrix (dimensioned array)
  • MAT array = expression – Set all elements to result of the expression
  • PRC.NAME -> This variable is a LIFO attribute-delimited stack of the processes that have been called. As one process calls another, the new process being called is pushed onto the beginning of the stack, and is popped off when that process terminates.
  • “/R” will refresh the screen when entered at an input prompt or menu.
  • “/DEBUG” will enter into debug mode.
  • “/COMMON” will show an interface for common variables like @KEY, @RECORD, @WORK, etc…
  • LOGIN -> Switch between GUI and CHAR mode
  • LISTU -> Check current login user in the system and from which account
  • LIST.READU -> Check current locked file by whom in the system
  • SORT BP LPTR -> direct query output to the printer specified by the SETPTR command
  • MODIFY filename F15 = “0” WITH F15 = “xxx”” (Change all record match F15 = “xxx” to “x” for filename, better to use SELECT to get a list with those need to be changed, be careful with this command!)
  • CALL SB.PROCESS(“ProcessName,Parameter)
  • SYS0017 -> Use it before calling a selection list process to allow vague search (make sure to start with the input field first when build the selection criteria in the selection list definition)
  • Use CLEARSELECT before to execute a UniQuery (SELECT statement) in BP program because the next SELECT statement will not clear the active list. (EXECUTE “CLEARSELECT” does not work in BP program)
  • User IPEX.EQUATES to build the EQU_XXX program
  • UniData Dynamic Array 3 Level Hierarchy -> DynamicArrayList<@AM,@VM,@SVM>  (e.g. ArrList<1,2,3>)
  • Use SYSTEM(12) to get the internal format of the system local time in milliseconds -> divide by 1000 to get the milliseconds part and use OCONV to get the HH:MM:SS part (i.e. HH:MM:SS.ttt)
UniQuery Reference :
  • As our default setup, our UniData environment is using PICK flavor (ECLTYPE -> 2  U_PSTYLEECL  ON). If a session has been set to ECLTYPE P and a command has been entered in lowercase case (the verb), the UniData (ECLTYPE U) parser is used for that command. For example, retrieve certain field without duplicate value by using UniQuery would be “select FILE WITH @ID LIKE …xxx… SAVING UNIQUE FIELDNAME NO.NULLS
Keyboard Shortcut:
  • Ctrl + P + A       -> copy
  • Ctrl + P + P       -> paste
  • Ctrl + P + U       -> switch to uppercase
  • Ctrl + P + L       -> switch to lowercase
  • Ctrl + P + T       -> switch to first letter capitalized
  • Ctrl + End         -> full line edit
  • Ctrl + W            -> switch between line edit and full screen edit mode when editing paragraph
  • Ctrl + C             -> type ABORT to get in SB+ shell (same as type 0 at Infoflo main menu), then MM (Cancel current process and go back to Infoflo main menu)
Unix Reference:
  • !who | grep userid -> check if a user is currently on the system (if userid is not in full, the system will do a vague search)
  • /backups/COPY_FILES/juntan
  • chmod 777 *
  • ls –l | pg
  • press ESC twice to recall previous used command