U2 XML Example

[Origin]: http://www.mvdeveloper.com/kb/docs/kb10.pdf

[Reference]: https://u2devzone.rocketsoftware.com/accelerate/articles/u2-xml/u2-xml

U2 XML Example

 

Below illustrates some U2 XDOM functions for working with an XML document.

The XML document should be placed in file &XML& with the ID of “SAMPLE.XML”

to work with this code.

This example was created in response to the follow message posted on the u2-users group

on 8th October 2008 which can be found at http://listserver.u2ug.org/.

 

XML from the message above cleaned up

 

Save this as “SAMPLE.XML” in file &XML&

Hello all,

I have to be able to parse out an XML file being sent by an

laboratory instrument.

Below is a sample file… I need to be able to get to the ID

attribute in SA, as well as the Key in AR, and AR’s data.

I need to do this in BASIC, and pass the parsed data to another

routine.

I’ve tried with OpenXMLData, ReadXMLData with an extraction file

that I’m not positive how to build (samples I found don’t deal with

attributes at all).

I also tried with the XDOMOpen/Locate/etc. with no luck either. I’m

about to go off and parse this thing myself but thought I’d try the

list before I do.

Any help is appreciated!

TIA,

Robert

 

<?xml version=”1.0″ encoding=”utf-8″?>

<?xml-stylesheet type=”text/xsl” <?xml version=”1.0″ encoding=”UTF-16″?>

<?xml-stylesheet type=”text/xsl” href=”C:\IRIS2K1\Templates\SpecimenAnalysis-style.xsl”?>

<SA BF=”URN” ID=”021305941″ SID=”AP” OP=”gloa” ADT=”2005-06-08 16:03:32-08:00″ ADTS=”2005-06-08 16:03:32″ RDT=”2005-06-10 17:15:44-

08:00″ RDTS=”2005-06-10 17:15:44″ RP=”2″ SQN=”0″ RSQN=”28″ DILN=”1″ DILD=”1″ IMP=”0″ CDT=”2005-06-08 16:03:32-08:00″ CDTS=”2005-06-08

16:03:32″ REDT=”2005-06-08 16:13:31-08:00″ REDTS=”2005-06-08 16:13:31″>

<PF></PF>

<PF></PF>

<PF></PF>

<PF></PF>

<PF></PF>

<PF></PF>

<PF></PF>

<AC AT=”Chemistry” AS=”Done” SO=”External”>

<AR Key=”GLU” SN=”GLU” LN=”Glucose” AF=”0″ NR=”30″>Neg</AR>

<AR Key=”PRO” SN=”PRO” LN=”Protein” AF=”0″ NR=”30″>Neg</AR>

<AR Key=”BIL” SN=”BIL” LN=”Bilirubin” AF=”0″ NR=”1+”>Neg</AR>

<AR Key=”URO” SN=”URO” LN=”Urobilinogen” AF=”1″ NR=”1+”>3+</AR>

<AR Key=”PH” SN=”PH” LN=”pH” AF=”1″ NR=”5.0″>5.0</AR>

<AR Key=”BLD” SN=”BLD” LN=”Blood” AF=”0″ NR=”Trace”>Neg</AR>

<AR Key=”KET” SN=”KET” LN=”Ketone” AF=”1″ NR=”1+”>2+</AR>

<AR Key=”NIT” SN=”NIT” LN=”Nitrite” AF=”1″ NR=”Pos”>Pos</AR>

<AR Key=”LEU” SN=”LEU” LN=”Leukocytes” AF=”1″ NR=”1+”>4+</AR>

<AR Key=”CLA” SN=”CLA” LN=”Clarity” AF=”0″ NR=”Hazy”>Clear</AR>

<AR Key=”SG” SN=”SPGR” LN=”Specific Gravity” AF=”0″ NR=”1.040″>1.015</AR>

<AR Key=”COL” SN=”COL” LN=”Color” AF=”0″ NR=”Amber”>Colorless</AR>

</AC>

<AC AT=”Sediment” AS=”Done” SO=”Internal”>

<AR Key=”ART” SN=”ART” LN=”Artifact” AF=”0″ NR=”99999999 /LPF”>[none]</AR>

<AR Key=”RBC” SN=”RBC” LN=”Red Blood Cell” AF=”1″ NR=”4 /uL”>33 /uL</AR>

<AR Key=”WBC” SN=”WBC” LN=”White Blood Cell” AF=”0″ NR=”6 /HPF”>[none]</AR>

<AR Key=”WBCC” SN=”WBCC” LN=”White Blood Cell Clump” AF=”1″ NR=”Occ”>Many</AR>

<AR Key=”BACT” SN=”BACT” LN=”Bacteria” AF=”0″ NR=”Few”>Rare</AR>

<AR Key=”BYST” SN=”BYST” LN=”Budding Yeast” AF=”0″ NR=”Few”>[none]</AR>

<AR Key=”HYST” SN=”HYST” LN=”Hyphae Yeast” AF=”0″ NR=”Few”>[none]</AR>

<AR Key=”SQEP” SN=”SQEP” LN=”Squamous Epithelial” AF=”0″ NR=”16 /HPF”>[none]</AR>

<AR Key=”TREP” SN=”TREP” LN=”Transitional Epithelial” AF=”0″ NR=”1 /HPF”>[none]</AR>

<AR Key=”REEP” SN=”REEP” LN=”Renal Epithelial” AF=”0″ NR=”1 /HPF”>[none]</AR>

<AR Key=”OVFB” SN=”OVFB” LN=”Oval Fat Body” AF=”0″ NR=”1 /LPF”>1 /LPF</AR>

<AR Key=”FAT” SN=”FAT” LN=”Fat” AF=”0″ NR=”1 /LPF”>[none]</AR>

<AR Key=”MUCS” SN=”MUCS” LN=”Mucous” AF=”0″ NR=”999999999 /LPF”>[none]</AR>

<AR Key=”RBCC” SN=”RBCC” LN=”Red Blood Cell Clump” AF=”0″ NR=”1 /LPF”>[none]</AR>

<AR Key=”SPRM” SN=”SPRM” LN=”Sperm” AF=”0″ NR=”[none]”>Rare</AR>

<AR Key=”TRCH” SN=”TRCH” LN=”Trichomonas” AF=”0″ NR=”Present”>[none]</AR>

<AR Key=”NSE” SN=”NSE” LN=”Non-Squamous Epithelial” AF=”0″ NR=”1 /HPF”>&lt; 1 /HPF</AR>

<AR Key=”UNCC” SN=”UNCC” LN=”Unclassified Cast” AF=”0″ NR=”1 /LPF”>[none]</AR>

<AR Key=”HYAL” SN=”HYAL” LN=”Hyaline Cast” AF=”0″ NR=”3-5″>[none]</AR>

<AR Key=”EPIC” SN=”EPIC” LN=”Epithelial Cast” AF=”0″ NR=”1 /LPF”>[none]</AR>

<AR Key=”WBCT” SN=”WBCT” LN=”White Blood Cell Cast” AF=”0″ NR=”1 /LPF”>[none]</AR>

<AR Key=”RBCT” SN=”RBCT” LN=”Red Blood Cell Cast” AF=”0″ NR=”1 /LPF”>[none]</AR>

<AR Key=”GRAN” SN=”GRAN” LN=”Granular Cast” AF=”0″ NR=”1 /LPF”>[none]</AR>

<AR Key=”CELL” SN=”CELL” LN=”Cellular Cast” AF=”0″ NR=”1 /LPF”>[none]</AR>

<AR Key=”BROAD” SN=”BROAD” LN=”Broad Cast” AF=”0″ NR=”1 /LPF”>[none]</AR>

<AR Key=”FATC” SN=”FATC” LN=”Fatty Cast” AF=”0″ NR=”1 /LPF”>[none]</AR>

<AR Key=”WAXY” SN=”WAXY” LN=”Waxy Cast” AF=”0″ NR=”1 /LPF”>[none]</AR>

<AR Key=”UNCX” SN=”UNCX” LN=”Unclassified Crystal” AF=”0″ NR=”1 /HPF”>1 /HPF</AR>

<AR Key=”TPO4″ SN=”TPO4″ LN=”Triphosphate Crystal” AF=”0″ NR=”FEW”>[none]</AR>

<AR Key=”CAOX” SN=”CAOX” LN=”Calcium Oxalate Crystal” AF=”0″ NR=”FEW”>[none]</AR>

<AR Key=”CAPH” SN=”CAPH” LN=”Calcium Phosphate Crystal” AF=”0″ NR=”FEW”>[none]</AR>

<AR Key=”CACB” SN=”CACB” LN=”Calcium Carbonate Crystal” AF=”0″ NR=”FEW”>[none]</AR>

<AR Key=”URIC” SN=”URIC” LN=”Uric Acid Crystal” AF=”0″ NR=”FEW”>[none]</AR>

<AR Key=”LEUC” SN=”LEUC” LN=”Leucine Crystal” AF=”0″ NR=”POS”>[none]</AR>

<AR Key=”CYST” SN=”CYST” LN=”Cystine Crystal” AF=”0″ NR=”POS”>[none]</AR>

<AR Key=”TYRO” SN=”TYRO” LN=”Tyrosine Crystal” AF=”0″ NR=”POS”>[none]</AR>

<AR Key=”AMOR” SN=”AMOR” LN=”Amorphous Crystal” AF=”0″ NR=”FEW”>[none]</AR>

<AR Key=”UNCL” SN=”UNCL” LN=”Unclassified” AF=”0″ NR=”99999999 /LPF”>[none]</AR>

<AR Key=”PC” SN=”PC” LN=”PC” AF=”0″ NR=”[none]”>1314 /uL</AR>

</AC>

<FL>CHEMCONFIRM</FL>

<CM>This sample is contaminated!! Comment appears here!!!</CM>

<ARV>42</ARV>

</SA>

 

Example Code

 

$INCLUDE UNIVERSE.INCLUDE XML.H

*

EQU TRUE TO 1

EQU FALSE TO 0

*

DIM SA.AC.NODES(10)

SA.NODE.CNT = 1

*

RTN.CODE = XDOMOpen(“SAMPLE.XML”, XML.FROM.FILE, XDOM)

IF RTN.CODE = XML.SUCCESS THEN

CRT “XML Document opened”

;* read attribute “ID” from node “SA”

XPATH = “/SA”

ATT.ID = “ID”

GOSUB 100

IF NOT(ERR) THEN

CRT “SA, Attribute (ID) = <“:VALUE:”>.”

*

;****************************************************************

;* find all our nodes with a path of /SA/AC

;* and store them in our dimensioned array SA.AC.NODES

;****************************************************************

XPATH = “/SA/AC”

GOSUB 200

*

IF NOT(ERR) THEN

SA.AC.NODES(SA.NODE.CNT) = FND.NODE

NEW.NODE = FND.NODE

LOOP

RTN.CODE = XDOMLocateNode(NEW.NODE, XDOM.NEXT.SIBLING.WITH.SAME.NAME, 1,

XDOM.ELEMENT.NODE, NEW.NODE)

WHILE RTN.CODE = XML.SUCCESS

SA.NODE.CNT += 1

SA.AC.NODES(SA.NODE.CNT) = NEW.NODE

REPEAT

END

*

;****************************************************************

;* loop through our found nodes and find our “AR” children

;****************************************************************

FOR X = 1 TO SA.NODE.CNT

;* print out our AC, AT attribute value

FND.NODE = SA.AC.NODES(X)

ATT.ID = “AT”

GOSUB 300

CRT ” “:VALUE

*

;* find our “AR” node

RTN.CODE = XDOMLocate(SA.AC.NODES(X), “AR”, “”, FND.NODE)

GOSUB 400

*

LOOP

RTN.CODE = XDOMLocateNode(FND.NODE, XDOM.NEXT.SIBLING.WITH.SAME.NAME, 1,

XDOM.ELEMENT.NODE, FND.NODE)

WHILE RTN.CODE = XML.SUCCESS

;* locate our text node in “AR” to get results

GOSUB 400

REPEAT

NEXT X

END

END ELSE

CRT “ERROR: unable to open xml document!”

END

RETURN

 

Example Code (cont)

*

100: *** read attribute from node ***

*

* XPATH (IN): path of the node to read

* ATT.ID (IN): id of the attribute to get the value of

*

* VALUE (OUT): value of the attribute, otherwise “”

* ERR (OUT): true if an error occurred

*

ERR = FALSE

*

VALUE = “”

GOSUB 200

IF NOT(ERR) THEN

GOSUB 300

END

RETURN

*

200: *** locate node ***

*

* XPATH (IN): path of the node to read

*

* FND.NODE (OUT): node that was found

* ERR (OUT): true if an error occurred

*

ERR = FALSE

RTN.CODE = XDOMLocate(XDOM, XPATH, “”, FND.NODE)

IF RTN.CODE # XML.SUCCESS THEN

CRT “ERROR: unable to locate XPATH <“:XPATH:”>”

ERR = TRUE

END

RETURN

*

300: *** read attribute ***

*

* ATT.ID (IN) : attribute to read

* FND.NODE (IN) : node to read attribute from

*

* VALUE (OUT): value of the attribute, otherwise “”

* ERR (OUT): true if an error occurred

*

ERR = FALSE

RTN.CODE = XDOMGetAttribute(FND.NODE, ATT.ID, ATT.NODE)

IF RTN.CODE = XML.SUCCESS THEN

RTN.CODE = XDOMGetNodeValue(ATT.NODE, VALUE)

END ELSE

CRT “ERROR: unable to read attribute <“:ATT.ID:”>”

ERR = TRUE

END

RETURN

*

400: *** read results and display ***

*

;* locate our text node in “AR” to get results

RTN.CODE = XDOMLocateNode(FND.NODE, XDOM.CHILD, XDOM.FIRST.CHILD, XDOM.TEXT.NODE, TEXT.NODE)

RTN.CODE = XDOMGetNodeValue(TEXT.NODE, TEXT.VALUE)

*

ATT.ID = “Key”

GOSUB 300

CRT ” “:VALUE:” = “:TEXT.VALUE

RETURN

*

END

 

Output

XML Document opened

SA, Attribute (ID) = <021305941>.

Chemistry

GLU = Neg

PRO = Neg

BIL = Neg

URO = 3+

PH = 5.0

BLD = Neg

KET = 2+

NIT = Pos

LEU = 4+

CLA = Clear

SG = 1.015

COL = Colorless

Sediment

ART = [none]

RBC = 33 /uL

WBC = [none]

WBCC = Many

BACT = Rare

BYST = [none]

HYST = [none]

SQEP = [none]

TREP = [none]

REEP = [none]

OVFB = 1 /LPF

FAT = [none]

MUCS = [none]

RBCC = [none]

SPRM = Rare

TRCH = [none]

NSE = < 1 /HPF

UNCC = [none]

HYAL = [none]

EPIC = [none]

WBCT = [none]

RBCT = [none]

GRAN = [none]

CELL = [none]

BROAD = [none]

FATC = [none]

WAXY = [none]

UNCX = 1 /HPF

TPO4 = [none]

CAOX = [none]

CAPH = [none]

CACB = [none]

URIC = [none]

LEUC = [none]

CYST = [none]

TYRO = [none]

AMOR = [none]

UNCL = [none]

PC = 1314 /uL

Advertisements

unibasic’s sort function

FROM: http://u2-universe-unidata.1073795.n5.nabble.com/unibasic-s-sort-function-td25339.html

RE: unibasic’s sort function

Edward Brown
81 posts
The SORT function (which I’m embarrassed to say I didn’t think existed,
and I’ve been coding unibasic for the last 8 or 9 years!) sorts the data
passed into it; there isn’t a return value. So

SORT(LIST)
CRT LIST

does work. Your original program sets LIST to 0 because LIST is set to
the return result of the sort statement – perhaps this should throw a
compiler error? Or perhaps there’s an undocumented return code if the
data could not be sorted?

Edward

An easier way to build XML in UniVerse

[Originally posted onhttps://gdoesu2.wordpress.com/2010/10/25/an-easier-way-to-build-xml-in-universe/

An easier way to build XML in UniVerse

The process of creating an XML document in UniVerse BASIC is quite laborious. It takes a number of steps to add a new element node, and similar steps to add attributes to a node.

The sequence is something like this:

  1. Create new XDOM.ELEMENT.NODE
  2. Add new node to existing XML document
  3. If the element is to have a value
    1. Create new XDOM.TEXT.NODE with the element node value
    2. Add text node to new element node
  4. If the element is to have attributes
    1. Create new XDOM.ATTR.NODE with attribute name and value
    2. Add attribute node to new element node
    3. Repeat for all required attributes

All this has create just on element. To create multiple elements requires performing the above sequence multiple times. This makes for a very messy and hard to maintain program.

An Easier way

Ordinarily, such a piece of logic would be placed into an external subroutine. That does work, but there is a way to provide a more intuitive solution: Functions!

UniVerse BASIC supports the creation and use of functions. By creating a function that performs this sequence, the process of building an XML document becomes a lot easier to code, and to read and maintain.

The Add_XMLElement function

The following code is a function that performs all the above steps:

function Add_XMLElement( domHandle, NODE.name, NODE.value, NODE.attr, NODE.ns, nodeHandle)

* This function adds a new element node to the domHandle XML doc.
* It also adds any attributes supplied.
*
* domHandle [IN]  Single Value
*   Handle to an XML node or document
*
* NODE.name [IN]  Single Value
*   Name of the element node to be added
*
* NODE.value [IN]  Single Value
*   The value of the new element node
*
* NODE.attr [IN]  Two attributes, with Multi values
*   Dynamic array of names and values to be used to define the
*   attributes on this node.
*   <1> Contains the attribute name
*   <2> Contains the attribute value
*
* NODE.ns [IN]  Single Value
*   The namespace to use for this node.
*
* nodeHandle [OUT]  Single Value
*   A handle to the added node
*
* Return Value
*   An XML return code: XML.SUCCESS, XML.ERROR, XML.INVALID.HANDLE

$include UNIVERSE.INCLUDE XML.H
xmlStatus = XML.SUCCESS

* Create the new ELEMENT node
xmlStatus = XDOMCreateNode( domHandle, NODE.name, "", XDOM.ELEMENT.NODE, nodeHandle)
if xmlStatus = XML.SUCCESS then
   xmlStatus = XDOMAddChild( domHandle, "", NODE.ns, nodeHandle, XDOM.NODUP)
end

if NODE.value # '' and xmlStatus = XML.SUCCESS then
   * If a value has been supplied, add a nameless child TEXT element
   xmlStatus = XDOMCreateNode(nodeHandle, '', NODE.value, XDOM.TEXT.NODE, newText)
   if xmlStatus = XML.SUCCESS then
      xmlStatus = XDOMAddChild( nodeHandle, "", NODE.ns, newText, XDOM.NODUP)
      xmlStatus = XDOMClose(newText)
   end
end

if NODE.attr # '' and xmlStatus = XML.SUCCESS then
   * If there are attribute to be added, do them now
   qty.ATTR = dcount( NODE.attr<1>, @VM)
   for num.ATTR = 1 to qty.ATTR while xmlStatus = XML.SUCCESS
      name.ATTR = NODE.attr<1,num.ATTR>
      if name.ATTR # '' then
         value.ATTR = NODE.attr<2,num.ATTR>
         xmlStatus = XDOMCreateNode( nodeHandle, name.ATTR, value.ATTR, XDOM.ATTR.NODE, attrHandle)
         if xmlStatus = XML.SUCCESS then
            xmlStatus = XDOMAddChild( nodeHandle, "", NODE.ns, attrHandle, XDOM.NODUP)
            xmlStatus = XDOMClose(attrHandle)
         end
      end
   next num.ATTR
end

return (xmlStatus)

Once compiled and cataloged, this function is available to be used.

A Working Example

This program uses the above function to create a sample XML document:

* manual build of xml using XDOM
$include UNIVERSE.INCLUDE XML.H
* Define the function we are going to use
deffun Add_XMLElement(a,b,c,d,e,f)

* Trying to build xml:
* <PurchaseHistory>
*   <PurchaseItem Ref="ABC123">Learning the Ropes</PurchaseItem>
*   <PurchaseItem Ref="CODE86">Getting Smarter</PurchaseItem>
*   <PurchaseItem Ref="CODE007" Security="High">Bonding the James Way</PurchaseItem>
* </PurchaseHistory>

* Create the doc
xmlStatus = XDOMCreateRoot(domHandle)

* Add the root element
xmlStatus = Add_XMLElement( domHandle, "PurchaseHistory", "", "", "", newnode)

* add the PurchaseItem elements
attrNode = "Ref": @AM: "ABC123"
xmlStatus = Add_XMLElement( newnode, "PurchaseItem", "Learning the Ropes", attrNode, "", subnode)
xmlStatus = XDOMClose(subnode)
attrNode = "Ref": @AM: "CODE86"
xmlStatus = Add_XMLElement( newnode, "PurchaseItem", "Getting Smarter", attrNode, "", subnode)
xmlStatus = XDOMClose(subnode)
attrNode = "Ref":@VM:"Security": @AM: "CODE007": @VM: "High"
xmlStatus = Add_XMLElement( newnode, "PurchaseItem", "Bonding the James Way", attrNode, "", subnode)
xmlStatus = XDOMClose(subnode)

* Output the XML
xmlStatus = XDOMWrite( domHandle, doc.XML, XML.TO.STRING)
crt "XML = "
crt "[":doc.XML:"]"

xmlStatus = XDOMClose(newnode)
xmlStatus = XDOMClose(domHandle)

As you can see, this is a much easier way of coding the manual build of XML, whilst maintaining the XDOM API-type function interface.

Compile and run this program, and it will produce the following output:

XML =
[<PurchaseHistory>
<PurchaseItem Ref=”ABC123″>Learning the Ropes</PurchaseItem>
<PurchaseItem Ref=”CODE86″>Getting Smarter</PurchaseItem>
<PurchaseItem Ref=”CODE007″ Security=”High”>Bonding the James Way</PurchaseItem>
</PurchaseHistory>
]