Problem using XMLLIB ?

Discussions related to the code libraries supplied with BB4W & BBCSDL
Mijndert Rooth
Posts: 5
Joined: Thu 23 Jul 2020, 14:38

Problem using XMLLIB ?

Post by Mijndert Rooth »

Seeking for a parser for JSON files, I looked into the XMLLIB how XML files are parsed.

The FN_getLevel(xmlobj{}) should return value zero at end-of-file condition.
FN_getLevel(xmlobj{})

FN_getLevel returns the current level in the hierarchy (where the base level is 1). It takes one parameter: the object structure returned by PROC_initXML.

At each level of nesting the value returned increases by one. If the returned value is zero it indicates an end-of-file condition (or that PROC_exitXML has been called).
I wrote a small program and find that at end-of-file the FN_getLevel(xmlobj{}) not returns value zero.
What am I doing wrong?

Here is my XML file:
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<Body>
<Data>
<DAY_ENERGY>
<Unit>Wh</Unit>
<Values>
<1>2763</1>
</Values>
</DAY_ENERGY>
<PAC>
<Unit>W</Unit>
<Values>
<1>1083</1>
</Values>
</PAC>
<TOTAL_ENERGY>
<Unit>Wh</Unit>
<Values>
<1>6670739</1>
</Values>
</TOTAL_ENERGY>
<YEAR_ENERGY>
<Unit>Wh</Unit>
<Values>
<1>3963848</1>
</Values>
</YEAR_ENERGY>
</Data>
</Body>
<Head>
<RequestArguments>
<DeviceClass>Inverter</DeviceClass>
<Scope>System</Scope>
</RequestArguments>
<Status>
<Code>0</Code>
<Reason></Reason>
<UserMessage></UserMessage>
</Status>
<Timestamp>2020-07-29T09:41:02+02:00</Timestamp>
</Head>
</root>
This is my program:
INSTALL @lib$+"XMLLIB"
REM xmlfile$ = "C:\Users\M\Documents\BBC BASIC for Windows\XML\example.xml"
xmlfile$ = "C:\Users\M\Documents\BBC BASIC for Windows\XML\GetInverterRealtimeData.xml"
outfile% = OPENOUT("C:\Users\M\Documents\BBC BASIC for Windows\XML\GetInverterRealtimeData.txt")

PROC_initXML(xmlobj{},xmlfile$)

line%=0

REPEAT
line%=line%+1

level% = FN_getLevel(xmlobj{})
PRINT "Level: ";level%;", ";

istag% = FN_isTag(xmlobj{})
PRINT "isTag: ";FN_TrueOrFalse(istag%);", ";

nexttoken$ = FN_nextToken(xmlobj{})
PRINT "Token: ";nexttoken$

PRINT #outfile%,"Level: "+STR$(level%)+", "+"isTag: "+FN_TrueOrFalse(istag%)+", "+"Token: "+nexttoken$

UNTIL line%=130

PROC_exitXML(xmlobj{})
CLOSE #0
END

DEF FN_TrueOrFalse(I%)
IF I%=-1 THEN ="TRUE"
IF I%=0 THEN ="FALSE"
=CHR$(I%) : REM Just in case
And this is the output with the last line indefenitly repeating when the REPEAT UNTIL loop tests for level%=0:
Level: 1, isTag: TRUE, Token: <?xml version="1.0" encoding="UTF-8" ?>
Level: 1, isTag: FALSE, Token:

Level: 1, isTag: TRUE, Token: <root>
Level: 2, isTag: FALSE, Token:

Level: 2, isTag: TRUE, Token: <Body>
Level: 3, isTag: FALSE, Token:

Level: 3, isTag: TRUE, Token: <Data>
Level: 4, isTag: FALSE, Token:

Level: 4, isTag: TRUE, Token: <DAY_ENERGY>
Level: 5, isTag: FALSE, Token:

Level: 5, isTag: TRUE, Token: <Unit>
Level: 6, isTag: FALSE, Token: Wh
Level: 6, isTag: TRUE, Token: </Unit>
Level: 5, isTag: FALSE, Token:

Level: 5, isTag: TRUE, Token: <Values>
Level: 6, isTag: FALSE, Token:

Level: 6, isTag: TRUE, Token: <1>
Level: 7, isTag: FALSE, Token: 2763
Level: 7, isTag: TRUE, Token: </1>
Level: 6, isTag: FALSE, Token:

Level: 6, isTag: TRUE, Token: </Values>
Level: 5, isTag: FALSE, Token:

Level: 5, isTag: TRUE, Token: </DAY_ENERGY>
Level: 4, isTag: FALSE, Token:

Level: 4, isTag: TRUE, Token: <PAC>
Level: 5, isTag: FALSE, Token:

Level: 5, isTag: TRUE, Token: <Unit>
Level: 6, isTag: FALSE, Token: W
Level: 6, isTag: TRUE, Token: </Unit>
Level: 5, isTag: FALSE, Token:

Level: 5, isTag: TRUE, Token: <Values>
Level: 6, isTag: FALSE, Token:

Level: 6, isTag: TRUE, Token: <1>
Level: 7, isTag: FALSE, Token: 1083
Level: 7, isTag: TRUE, Token: </1>
Level: 6, isTag: FALSE, Token:

Level: 6, isTag: TRUE, Token: </Values>
Level: 5, isTag: FALSE, Token:

Level: 5, isTag: TRUE, Token: </PAC>
Level: 4, isTag: FALSE, Token:

Level: 4, isTag: TRUE, Token: <TOTAL_ENERGY>
Level: 5, isTag: FALSE, Token:

Level: 5, isTag: TRUE, Token: <Unit>
Level: 6, isTag: FALSE, Token: Wh
Level: 6, isTag: TRUE, Token: </Unit>
Level: 5, isTag: FALSE, Token:

Level: 5, isTag: TRUE, Token: <Values>
Level: 6, isTag: FALSE, Token:

Level: 6, isTag: TRUE, Token: <1>
Level: 7, isTag: FALSE, Token: 6670739
Level: 7, isTag: TRUE, Token: </1>
Level: 6, isTag: FALSE, Token:

Level: 6, isTag: TRUE, Token: </Values>
Level: 5, isTag: FALSE, Token:

Level: 5, isTag: TRUE, Token: </TOTAL_ENERGY>
Level: 4, isTag: FALSE, Token:

Level: 4, isTag: TRUE, Token: <YEAR_ENERGY>
Level: 5, isTag: FALSE, Token:

Level: 5, isTag: TRUE, Token: <Unit>
Level: 6, isTag: FALSE, Token: Wh
Level: 6, isTag: TRUE, Token: </Unit>
Level: 5, isTag: FALSE, Token:

Level: 5, isTag: TRUE, Token: <Values>
Level: 6, isTag: FALSE, Token:

Level: 6, isTag: TRUE, Token: <1>
Level: 7, isTag: FALSE, Token: 3963848
Level: 7, isTag: TRUE, Token: </1>
Level: 6, isTag: FALSE, Token:

Level: 6, isTag: TRUE, Token: </Values>
Level: 5, isTag: FALSE, Token:

Level: 5, isTag: TRUE, Token: </YEAR_ENERGY>
Level: 4, isTag: FALSE, Token:

Level: 4, isTag: TRUE, Token: </Data>
Level: 3, isTag: FALSE, Token:

Level: 3, isTag: TRUE, Token: </Body>
Level: 2, isTag: FALSE, Token:

Level: 2, isTag: TRUE, Token: <Head>
Level: 3, isTag: FALSE, Token:

Level: 3, isTag: TRUE, Token: <RequestArguments>
Level: 4, isTag: FALSE, Token:

Level: 4, isTag: TRUE, Token: <DeviceClass>
Level: 5, isTag: FALSE, Token: Inverter
Level: 5, isTag: TRUE, Token: </DeviceClass>
Level: 4, isTag: FALSE, Token:

Level: 4, isTag: TRUE, Token: <Scope>
Level: 5, isTag: FALSE, Token: System
Level: 5, isTag: TRUE, Token: </Scope>
Level: 4, isTag: FALSE, Token:

Level: 4, isTag: TRUE, Token: </RequestArguments>
Level: 3, isTag: FALSE, Token:

Level: 3, isTag: TRUE, Token: <Status>
Level: 4, isTag: FALSE, Token:

Level: 4, isTag: TRUE, Token: <Code>
Level: 5, isTag: FALSE, Token: 0
Level: 5, isTag: TRUE, Token: </Code>
Level: 4, isTag: FALSE, Token:

Level: 4, isTag: TRUE, Token: <Reason>
Level: 5, isTag: TRUE, Token: </Reason>
Level: 4, isTag: FALSE, Token:

Level: 4, isTag: TRUE, Token: <UserMessage>
Level: 5, isTag: TRUE, Token: </UserMessage>
Level: 4, isTag: FALSE, Token:

Level: 4, isTag: TRUE, Token: </Status>
Level: 3, isTag: FALSE, Token:

Level: 3, isTag: TRUE, Token: <Timestamp>
Level: 4, isTag: FALSE, Token: 2020-07-29T09:41:02+02:00
Level: 4, isTag: TRUE, Token: </Timestamp>
Level: 3, isTag: FALSE, Token:

Level: 3, isTag: TRUE, Token: </Head>
Level: 2, isTag: FALSE, Token:

Level: 2, isTag: TRUE, Token: </root>
Level: 1, isTag: FALSE, Token:

Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
Level: 1, isTag: FALSE, Token:
What am I doing wrong?
Acorn BBC Micro, model B with 6502 Second Processor.
RichardRussell

Re: Problem using XMLLIB ?

Post by RichardRussell »

Mijndert Rooth wrote: Wed 05 Aug 2020, 13:59 What am I doing wrong?
The documentation is wrong, or at least misleading. FN_getLevel definitely returns zero after PROC_exitXML has been called, but what it returns at the end-of-file depends on the contents of the file itself, and specifically whether all the tags are correctly paired; you cannot rely on it returning zero at EOF. I will amend the manual to remove the reference to end-of-file there.

It's FN_skipTo and FN_skipToRet that are guaranteed to return zero at end-of-file. Here is a simplified extract from the supplied example program Ceefax.bbc showing an example of its use:

Code: Select all

      PROC_initXML(xml{},@tmp$+"ceefax.rss")
      WHILE FN_skipTo(xml{},"item",0)
        I% = FN_getLevel(xml{})
        IF FN_skipTo(xml{},field$,I%) THEN
          rss$ = FN_repEnt(FN_nextToken(xml{}))
          array$(P%) = rss$
          P% += 1
        ENDIF
      ENDWHILE
      PROC_exitXML(xml{})
Mijndert Rooth
Posts: 5
Joined: Thu 23 Jul 2020, 14:38

Re: Problem using XMLLIB ?

Post by Mijndert Rooth »

Richard,

Thank you for your clarification.
Acorn BBC Micro, model B with 6502 Second Processor.