TextReader Parser
Prev | Chapter 2. Parsers |

## TextReader Parser

Like the SAX parser, the TextReader parser is suitable for sequential parsing, but instead of implementing handlers for specific parts of the document, it allows you to detect the current node type, process the node accordingly, and skip forward in the document as much as necessary. Unlike the DOM parser, you may not move backwards in the XML document. And unlike the SAX parser, you must not waste time processing nodes that do not interest you.

All methods are on the single parser instance, but their result depends on the current context. For instance, use `read()` to move to the next node, and `move_to_element()` to navigate to child nodes. These methods will return false when no more nodes are available. Then use methods such as `get_name()` and `get_value()` to examine the elements and their attributes.

### Example

This example examines each node in turn, then moves to the next node.

Source Code

File: `main.cc`

    #include <libxml++/libxml++.h>
    #include <cstdlib>
    #include <iostream>

    struct indent {
      int depth_;
      explicit indent(int depth): depth_(depth) {};
    };

    std::ostream & operator<<(std::ostream & o, indent const & in)
    {
      for(int i = 0; i != in.depth_; ++i)
      {
        o << "  ";
      }
      return o;
    }

    std::ostream& operator<<(std::ostream& o, const std::optional<xmlpp::ustring>& s)
    {
      o << s.value_or("{[(no value)]}");
      return o;
    }

    int main(int /* argc */, char** /* argv */)
    {
      try
      {
        xmlpp::TextReader reader("example.xml");

        while(reader.read())
        {
          int depth = reader.get_depth();
          std::cout << indent(depth) << "--- node ---" << std::endl;
          std::cout << indent(depth) << "name: " << reader.get_name2() << std::endl;
          std::cout << indent(depth) << "depth: " << reader.get_depth() << std::endl;

          if(reader.has_attributes())
          {
            std::cout << indent(depth) << "attributes: " << std::endl;
            std::cout << indent(depth) << "attribute 0: " << reader.get_attribute2(0) << std::endl;
            std::cout << indent(depth) << "attribute 9: " << reader.get_attribute2(9) << std::endl;
            reader.move_to_first_attribute();
            do
            {
              std::cout << indent(depth) << "  " << reader.get_name2() << ": " << reader.get_value2() << std::endl;
            } while(reader.move_to_next_attribute());
            reader.move_to_element();
          }
          else
          {
            std::cout << indent(depth) << "no attributes" << std::endl;
          }

          std::cout << indent(depth) << "value: '" << reader.get_value2() << "'" << std::endl;
        }
      }
      catch(const std::exception& e)
      {
        std::cerr << "Exception caught: " << e.what() << std::endl;
        return EXIT_FAILURE;
      }
      return EXIT_SUCCESS;
    }

Prev | Up |
SAX Parser | Home |