Still in need of tweaking, but the basics are done for a rudimentary
generic XML SAX parser. The results when run against a few varieties of xml doc I found follow. [psharp@fedora GenericXMLParser]$ cat ./sample.xml;java TestKeyParser ./sample.xml <users> <user id="100"> <firstName>John</firstName> <lastName>Doe</lastName> </user> <user id="101"> <firstName>Jane</firstName> <lastName>Doe</lastName> </user> <user id="102"> <firstName>HowToDo</firstName> <lastName>InNetRexx</lastName> </user> </users> [users, user.id=100, firstName=John, lastName=Doe, user.id=101, firstName=Jane, lastName=Doe, user.id=102, firstName=HowToDo, lastName=InNetRexx] [psharp@fedora GenericXMLParser]$ cat ./MyProps.xml;java TestKeyParser ./MyProps.xml <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd "> <properties> <comment>application.properties</comment> <entry key="input.dir">c:/temp/input</entry> <entry key="spring.batch.job.enabled">false</entry> <entry key="spring.main.banner-mode">off</entry> </properties> [properties, comment=application.properties, entry.key=input.dir, entry=c:/temp/input, entry.key=spring.batch.job.enabled, entry=false, entry.key=spring.main.banner-mode, entry=off] [psharp@fedora GenericXMLParser]$ cat ./append.xml;java TestKeyParser ./append.xml <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd "> <project name="MyProject" basedir="."> <description> demonstration of ant jsr223 netrexx scripting </description> <property name="divider" value="81" /> <script language="netrexx" manager="javax"> say "100/"divider '= ' 100/divider </script> </project> [project.name=MyProject, project.basedir=., description=demonstration of ant jsr223 netrexx scripting, property.name=divider, property.value=81, script.language=netrexx, script.manager=javax, script=say "100/"divider '= ' 100/divider] [psharp@fedora GenericXMLParser]$ I switched the InputSource in the sample SAXXMLParser from File to String. Since the ultimate goal is to parse MQFTE logger messages (xml), converting to a generic String source was logical. >> FileToStr.nrx: --file\FileToStr.nrx import java.io.File import java.io.FileInputStream import java.io.FileNotFoundException class FileToStr public Properties private lines = String method loadFile(fileName=String) -- read whole file is = BufferedReader(FileReader(fileName)) line=is.readLine() -- read first line if line \= null then this.lines = line.trim() line=is.readLine() loop while line \= null this.lines = lines||line.trim() line=is.readLine() end is.close() method getFile returns String return lines >> Mainline TestKeyParser.nrx: --package com.howtodoinnrx.xml.sax import java.util.ArrayList class TestKeyParser public method main(args=String[]) static signals FileNotFoundException --xmlFile=File(args[0]) lines=fileToStr() lines.loadFile(args[0]) parser=KeysXmlParser() --keys=parser.parseXml(FileInputStream(xmlFile)) keys=parser.parseXml(lines.getFile()) say keys >> Keys.xml: --package com.howtodoinnrx.xml.sax class Key public properties private keyName=String keyAttr=String keyValue=String method getKeyName returns String return keyName method setKeyName(keyName_arg=String) this.keyName=keyName_arg method getKeyAttr returns String return keyAttr method setKeyAttr(keyAttr_arg=String) this.keyAttr=keyAttr_arg method getKeyValue returns String return keyValue method setKeyValue(keyValue_arg=String) this.keyValue=keyValue_arg method toString returns String if this.keyAttr == "" then if this.keyValue == "" then return this.keyName else return this.keyName"="this.keyValue else return this.keyName"."this.keyAttr"="this.keyValue >> KeysXMLParser.xml: --package com.howtodoinnrx.xml.sax import java.util.ArrayList import javax.xml.parsers import org.xml.sax.InputSource import org.xml.sax.SAXException import org.xml.sax.XMLReader import org.xml.sax.helpers.XMLReaderFactory class KeysXmlParser public --method parseXml(in=InputStream) returns ArrayList method parseXml(in=String) returns ArrayList keys=ArrayList() do true=Int 1 handler=KeyParserHandler() --parser=XMLReaderFactory.createXMLReader() saxpf=SAXParserFactory.newInstance() saxpf.setNamespaceAware(true) parser=saxpf.newSAXParser().getXMLReader() parser.setContentHandler(handler) source=InputSource(StringReader(in)) handler.setXML(in) parser.parse(source) keys=handler.getKeys() catch e=SAXException e.printStackTrace() catch ex=IOException ex.printStackTrace() finally end return keys >> and the meat is in KeysParserHandler.xml: --package com.howtodoinnrx.xml.sax import java.util.ArrayList import java.util.Stack import org.xml.sax.Attributes import org.xml.sax.SAXException import org.xml.sax.helpers.DefaultHandler class KeyParserHandler public extends DefaultHandler properties private keyList=ArrayList() attrList=ArrayList() elementStack=Stack() objectStack=Stack() xmlStr=Rexx() aL=Int xmlCurPos=Int method startDocument method endDocument method startElement(uri=String,localName=String,qName=String,attrs=Attributes) this.aL=attrs.getLength() --aI=attrs.getIndex(qName) --say "startElement:<qName>"qName"<uri>"uri"<localName>"localName"<Index>"aI"<Length>"aL -- advance pointer past qName advance('<'qName) this.attrList.clear() --say xmlStr xmlCurPos this.elementStack.push(qName) key_nrx=Key() key_nrx.setKeyName(qName) key_nrx.setKeyAttr(String "") key_nrx.setKeyValue(String "") if aL>0 then loop for aL attrEnd=xmlStr.pos('=',xmlCurPos) attrStart=xmlStr.verify(' ','N',xmlCurPos+1) --say "attr:" attrStart attrEnd attrName=String xmlStr.substr(attrStart,attrEnd-attrStart) advance(attrName'=') value=attrs.getValue(attrName) advance(value) --say "attr:<value>"attrName"="value --key_nrx.setKeyAttrName(value) key_attr=Key() key_attr.setKeyName(qName) key_attr.setKeyAttr(attrName) key_attr.setKeyValue(value) this.keyList.add(key_attr) --say key_attr end endElem=xmlStr.pos("><",xmlCurPos) verPos=xmlStr.verify(" >","N",xmlCurPos) --say "endElem="endElem xmlStr.substr(endElem-5,10) "verPos="verPos xmlStr.substr(verPos-5,10) "curPos="xmlCurPos xmlStr.substr(xmlCurPos-5,10) if verPos>=endElem then do this.keyList.add(key_nrx) --say key_nrx end this.objectStack.push(key_nrx) method endElement(uri=String,localName=String,qName=String) --say "endElement:<uri>"uri"<localName>"localName"<qName>"qName this.elementStack.pop() this.objectStack.pop() advance("/") method characters(ch=char[],start=int,len=int) value=String(ch,start,len).trim() --say "characters:<start>"start"<length>"len"<value>"value"<currElem>"currentElement() key_nrx=Key() key_nrx.setKeyName(currentElement()) key_nrx.setKeyAttr(String "") if value.length()\==0 then key_nrx.setKeyValue(value) else key_nrx.setKeyValue(String "") this.keyList.add(key_nrx) --say key_nrx method currentElement private returns String return String this.elementStack.peek() method getKeys returns ArrayList return keyList method setXML(data=String) this.xmlStr=(Rexx data) this.xmlCurPos=0 method advance(data=String) --was=xmlCurPos this.xmlCurPos=xmlCurPos+xmlStr.substr(xmlCurPos+1).pos(data)+data.length() --say "advance" was xmlCurPos _______________________________________________ Ibm-netrexx mailing list [hidden email] Online Archive : http://ibm-netrexx.215625.n3.nabble.com/ |
Note that converting the input to a string is also a key part of the
generic parser solution. This is because element attributes are only retrievable by name which must be known. So I added the setXML method to the handler as a means of exposing the XML source independently from the SAX parser feed. _______________________________________________ Ibm-netrexx mailing list [hidden email] Online Archive : http://ibm-netrexx.215625.n3.nabble.com/ |
Nice to see you are moving on.
java2nrx will convert some java code for you to help you learn. https://sourceforge.net/p/netrexx/code/ci/master/tree/tools/java2nrx/ The version I have has a few extra fixes but it has been so long I do not remember what. I created a tick against the javaparser project but it took years for them to close it an their code is totally different now. As you learn, more and more of the Java types can become Rexx types. _______________________________________________ Ibm-netrexx mailing list [hidden email] Online Archive : http://ibm-netrexx.215625.n3.nabble.com/ |
Free forum by Nabble | Edit this page |