/* purpose: demonstrate how to list the element names in document order */

parse arg xmlFileName

   /* create an instance of the JAXP DocumentBuilderFactory    */
factory=bsf.loadClass("javax.xml.parsers.DocumentBuilderFactory")~newInstance
factory~setNamespaceAware(.true)    -- set desired parser to namespace aware
parser=factory~newDocumentBuilder   -- create the parser from the factory

eh=.errorHandler~new       -- create an error handler Rexx object
   -- wrap up the Rexx error handler as a Java object
javaEH=BsfCreateRexxProxy(eh, , "org.xml.sax.ErrorHandler")
parser~setErrorHandler(javaEH)   -- set the error handler for this parser

rootNode=parser~parse(xmlFileName)  -- parse the file, returns root node

   /* get constant value to determine node types to filter     */
.local~show_element=bsf.getConstant("org.w3c.dom.traversal.NodeFilter", "SHOW_ELEMENT")
whatToShow=.show_element

   /* create a TreeWalker with only Element nodes              */
walker=rootNode~createTreeWalker(rootNode, whatToShow, .nil, .true)

   /* process list of Element nodes                            */
call walkTheTree walker~firstChild, 0


::requires BSF.CLS      /* get the Java support */

::routine walkTheTree   /* walk the tree recursively                 */
  use arg node, level

  say "   "~copies(level) || pp(node~getNodeName)  -- show element name indented

  child=node~firstChild       -- depth first
  do while child<>.nil
      -- there may be other node types coming with elements in a TreeWalker
     if child~getNodeType=.show_element then -- make sure only element nodes
        call walkTheTree child, level+1      -- recurse, increase level

     child=child~nextSibling  -- breadth next
  end


::class ErrorHandler    -- a Rexx error handler ("org.xml.sax.ErrorHandler")

::method unknown        /* handles "warning", "error" and "fatalError" events */
  use arg methName, argArray  -- arguments from the Java SAX parser
  exception=argArray[1] -- retrieve SAXException argument
  .error~say(methName":" -
             "line="exception~getLineNumber",col="exception~getColumnNumber":" -
             pp(exception~getMessage))