/* Example of c++ code: xmlDocPtr doc; xmlNodePtr cur; doc = xmlParseFile(docname.c_str()); if (doc == NULL ) { fprintf(stderr,"Document not parsed successfully. \n"); return; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { fprintf(stderr,"empty document\n"); xmlFreeDoc(doc); return; } cur = cur->xmlChildrenNode; while (cur != NULL) { printf("child: %s\n", cur->name); cur = cur->next; } */ /* Default strategies: - what to do with unspecified nodes Node content strategy: - send as-is - apply transforms (all / named) - ?? skip Processing order: - dependencies */ default_filname = "project/documentation.fodt" : string; /* require ptrvalid */ /* local scope doc ptr */ XmlNode = type { tag: string; attrs: [string]; content: string}. Tree = type(Leaf) Tree [Leaf; [Tree(Leaf)]]; XmlTree = Tree(XmlNode); children = function: (tree: xmlNodePtr)->XmlTree { childrenRaw = tree[xmlChildrenNode]: [xmlNodePtr], linkedlist(next, null); map (childrenRaw->childRaw: xmlNodePtr) { Tree[childRaw[name] children(childRaw)] } } document = function: (filename: string)->XmlTree { docRaw = xmlParseFile(docname.c_str()) : xmlDocPtr; nodeRaw= xmlDocGetRootElement(docRaw) : xmlNodePtr; Tree [nodeRaw[name] children(nodeRaw)); } query = function(tree: XmlTree): [XmlTree] { children : context(children) = case default [] case (tree[0]: NeedChildren(childrenFilters), ApplyTransform(transFilters)) { loop fold (tree[1]->child: Tree(Leaf) | childrenFilters; []->accum). {accum + traverse(child): cases(transFilters) }; } node = case (node.tag == "style:style"; class = node[attrs, "style:name"]; exists(class, ParaKnownClasses)) { [class, node[attrs, "style:display-name"]]; } case default [] ; Tree[node children] | node + children } test = function: ()->num { data = query(document(default_filename)): [string, string]; exists(data, "pgess1"). } /* traverse = function(trees: [XmlTree]) : [XmlTree] loop fold(trees->tree: Tree; []->acc) acc + traverse(tree) */