/* C++ SECTION 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; } */ /* FEATURES SECTION Default strategies: - what to do with unspecified nodes Node content strategy: - send as-is - apply transforms (all / named) - ?? skip Processing order: - dependencies Mapping: * tree -> list */ /* TODO SECTION -- gather types aliases (tree->list mapping) -- flyweight implementation ('doc' field calculation, for example. based on are there more than one opened document ) */ // REQUIREMENTS SECTION /* require ptrvalid */ /* local scope doc ptr */ /* singleton element check(::single) */ XmlAttr = type alias { name:: string, content:: string }. XmlNode = type alias { name:: string, /* the name of the node, or the entity */ content:: string, /* the content */ attributes::[XmlAttr] /* properties list */ /* children:: [xmlNode], // parent->childs link void *_private; // application data struct _xmlNode *parent; // child->parent link struct _xmlNode *next; // next sibling link struct _xmlNode *prev; // previous sibling link struct _xmlDoc *doc; // the containing document unsigned short line; // line number */ }. interface(extern-c){ xml2 = library:: pkgconfig("libxml-2.0"). include { xml2 = ["libxml/tree.h", "string.h"] }. } Tree = type Tree(Leaf) [Leaf, [Tree(Leaf)]]. XmlTree = type alias Tree(XmlNode). toXmlNode = function (nodeRaw:: xmlNodePtr):: XmlNode { propertiesRaw = nodeRaw["properties"]:: [xmlAttrPtr]; containers:linkedlist(next, null). properties = loop map(propertiesRaw -> property::xmlAttrPtr)::[XmlAttr]{ {name=property["name"], content=property["children", "content"]} }. {name = nodeRaw["name"], content=nodeRaw["content"], attributes=properties} } children = function(nodeRaw::xmlDocPtr)::[XmlTree] { childrenRaw = nodeRaw["children"]:: [xmlDocPtr]; containers:linkedlist(next, null). children = loop map(childrenRaw->child:: xmlDocPtr) :: [XmlTree]{ [toXmlNode(child), children(child)] }. children } document = function (filename:: string):: XmlTree { docRaw = xmlParseFile(filename) :: xmlDocPtr. nodeRaw= xmlDocGetRootElement(docRaw) :: xmlNodePtr. [toXmlNode(nodeRaw), children(nodeRaw)]:: XmlTree } traverse = function(tree:: XmlTree) :: [XmlNode] { listOfNodes = loop fold(tree -> node:: XmlTree, []->acc):: [XmlNode]{ acc + node[0] + traverse(node[1]):: [XmlNode] }. listOfNodes } test1 = function:: int; entry { filename = "project/documentation.fodt" :: string. root = document(filename):: XmlTree. nodesAll = traverse(root):: [XmlNode]. result = loop fold(nodesAll->node:: XmlNode, 0->count):: int{ count + if (0==strcmp(node["name"], "section")) :: int { 1 } else { 0 } }. result }