XML to Mapping

[ Start > PikeHints > XML to Mapping ] [ Edit this Page | Show Page Versions | Show Raw Source ]

The following is a simple demo of the XML Tree parser module. The code reads an XML file, parses it into a tree and then turns it into a pike mapping.

Note: Using a tree is fine for small fragments of XML, but can rapidly eat up CPU time and memory. In those cases, you probably want to parse the xml in a streaming manner, only saving the bits you need.

Given the following input file:

<?xml version="1.0" encoding="UTF-8"?>
<server_uuid>some uuid data</server_uuid>

<name>jsmith</name> <admin>TRUE</admin> </user></contents> </reply>

The resulting mapping is generated:

([ /* 1 element */
  "reply": ([ /* 3 elements */
      "contents": ([ /* 7 elements */
          "loaded_plugin_set": "201204110537",
          "msp": "FALSE",
          "plugin_set": "201204110537",
          "scanner_boottime": "1331388234",
          "server_uuid": ">some uuid data",
          "token": "askldjfklasdfjlasdf",
          "user": ([ /* 2 elements */
              "admin": "TRUE",
              "name": "ldillon"
      "seq": "0",
      "status": "OK"

Here's the code:

int main()
  // parse a text file into a tree
  object t = Parser.XML.Tree.parse_file("test.xml");

// convert the tree to a mapping mapping m = xml_to_mapping(t);

// print out the result werror("m: %O&#110;", m);

return 0; }

mapping xml_to_mapping(object n) { mapping m = ([]);

// for each child of the tree's root, call the function build_mapping. n->iterate_children(build_mapping, m); return m; }

string|mapping build_mapping(mixed children, mixed|void map) { if(!map) map = ([]);

// if called recursively, handle a whole sub-level of xml. if(arrayp(children)) { foreach(children;; mixed child) { if(child->get_node_type() == Parser.XML.Tree.XML_ELEMENT) map[child->get_full_name()] = build_mapping2(child->get_children()); }

// if there were some key-value pairs present (like a subtree), we can return them if(sizeof(map)) return map; // otherwise, assume it was just a value without any subtree. else return children->get_text() * ""; } else // if we're called directly from iterate_*(), behave slightly differently. { if(children->get_node_type() != Parser.XML.Tree.XML_ELEMENT) return 0; map[children->get_full_name()] = build_mapping2(children->get_children()); return 0; } }

Poppa's SimpleXML module

Provides similar functionality to the PHP simplexml class.


Powered by PikeWiki2

gotpike.org | Copyright © 2004 - 2009 | Pike is a trademark of Department of Computer and Information Science, Linköping University