--- /dev/null
+
+#include <cassert>
+#include <GdomeSmartDOM.hh>
+
+namespace DOM = GdomeSmartDOM;
+
+unsigned n_elements;
+unsigned n_leaf_elements;
+unsigned n_text_nodes;
+unsigned n_blank_text_nodes;
+unsigned n_attributes;
+unsigned max_attributes;
+unsigned max_depth;
+unsigned max_children;
+
+bool
+is_blank(const std::string& s)
+{
+ for (int i = 0; i < s.length(); i++)
+ if (!isblank(s[i])) return false;
+ return true;
+}
+
+void
+visit(DOM::Node node, unsigned depth)
+{
+ assert(node);
+
+ max_depth = std::max(max_depth, depth);
+
+ switch (node.get_nodeType())
+ {
+ case DOM::Node::ELEMENT_NODE:
+ {
+ n_elements++;
+ const unsigned n_attrs = node.get_attributes().get_length();
+ n_attributes += n_attrs;
+ max_attributes = std::max(max_attributes, n_attrs);
+ if (!node.get_firstChild()) n_leaf_elements++;
+ }
+ break;
+ case DOM::Node::TEXT_NODE:
+ n_text_nodes++;
+ if (is_blank(node.get_nodeValue())) n_blank_text_nodes++;
+ break;
+ case DOM::Node::ATTRIBUTE_NODE:
+ break;
+ }
+
+ unsigned n_children = 0;
+ for (DOM::Node p = node.get_firstChild(); p; p = p.get_nextSibling())
+ {
+ visit(p, depth + 1);
+ n_children++;
+ }
+ max_children = std::max(max_children, n_children);
+}
+
+void
+print_results(const std::string& URI)
+{
+ std::cout << "<stats for=\"" << URI << "\">" << std::endl;
+ std::cout << " <depth>" << max_depth << "</depth>" << std::endl;
+ std::cout << " <elements>" << std::endl;
+ std::cout << " <total>" << n_elements << "</total>" << std::endl;
+ std::cout << " <leaf>" << n_leaf_elements << "</leaf>" << std::endl;
+ std::cout << " </elements>" << std::endl;
+ std::cout << " <text-nodes>" << std::endl;
+ std::cout << " <total>" << n_text_nodes << "</total>" << std::endl;
+ std::cout << " <blank>" << n_blank_text_nodes << "</blank>" << std::endl;
+ std::cout << " </text-nodes>" << std::endl;
+ std::cout << " <attributes>" << std::endl;
+ std::cout << " <total>" << n_attributes << "</total>" << std::endl;
+ std::cout << " <max>" << max_attributes << "</max>" << std::endl;
+ std::cout << " </attributes>" << std::endl;
+ std::cout << " <children>" << std::endl;
+ std::cout << " <max>" << max_children << "</max>" << std::endl;
+ std::cout << " </children>" << std::endl;
+ std::cout << "</stats>" << std::endl;
+}
+
+int
+main(int argc, char* argv[])
+{
+ DOM::DOMImplementation di;
+ DOM::Document doc = di.createDocumentFromURI(argv[1]);
+ visit(doc, 0);
+ print_results(argv[1]);
+}
--- /dev/null
+<?xml version="1.0"?>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:param name="URI" select="''"/>
+
+<xsl:output method="xml"/>
+
+<xsl:template match="/">
+<stats for="{$URI}">
+ <xsl:message>Computing max depth...</xsl:message>
+ <max-depth>
+ <xsl:call-template name="max-depth2"/>
+ </max-depth>
+ <xsl:message>Computing number of nodes...</xsl:message>
+ <number-of-elements>
+ <xsl:call-template name="number-of-elements"/>
+ </number-of-elements>
+ <number-of-text-nodes>
+ <xsl:call-template name="number-of-text-nodes"/>
+ </number-of-text-nodes>
+ <number-of-blank-text-nodes>
+ <xsl:call-template name="number-of-blank-text-nodes"/>
+ </number-of-blank-text-nodes>
+ <xsl:message>Computing number of leaves...</xsl:message>
+ <number-of-leaves>
+ <xsl:call-template name="number-of-leaves"/>
+ </number-of-leaves>
+</stats>
+</xsl:template>
+
+<xsl:template name="number-of-elements">
+ <xsl:value-of select="count(//*)"/>
+</xsl:template>
+
+<xsl:template name="number-of-text-nodes">
+ <xsl:value-of select="count(//text())"/>
+</xsl:template>
+
+<xsl:template name="number-of-blank-text-nodes">
+ <xsl:value-of select="count(//text()[normalize-space(.) = ''])"/>
+</xsl:template>
+
+<xsl:template name="number-of-leaves">
+ <xsl:value-of select="count(//text()|//*[not(child::node())])"/>
+</xsl:template>
+
+<xsl:template name="max-depth-aux">
+ <xsl:param name="nodes" select="/.."/>
+ <xsl:param name="depth" select="0"/>
+ <xsl:param name="DEPTH" select="0"/>
+ <xsl:choose>
+ <xsl:when test="$nodes">
+ <xsl:variable name="head-depth">
+ <xsl:call-template name="max-depth-aux">
+ <xsl:with-param name="nodes" select="$nodes[1]/*"/>
+ <xsl:with-param name="depth" select="$depth + 1"/>
+ <xsl:with-param name="DEPTH" select="$DEPTH"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="NEW_DEPTH">
+ <xsl:choose>
+ <xsl:when test="$head-depth > $DEPTH">
+ <xsl:value-of select="$head-depth"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$DEPTH"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:call-template name="max-depth-aux">
+ <xsl:with-param name="nodes" select="$nodes[position() > 1]"/>
+ <xsl:with-param name="depth" select="$depth"/>
+ <xsl:with-param name="DEPTH" select="$NEW_DEPTH"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$depth > $DEPTH">
+ <xsl:value-of select="$depth"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$DEPTH"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="max-depth">
+ <xsl:call-template name="max-depth-aux">
+ <xsl:with-param name="nodes" select="//node()"/>
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="max-depth2-aux">
+ <xsl:param name="nodes" select="/.."/>
+ <xsl:param name="DEPTH" select="0"/>
+ <xsl:choose>
+ <xsl:when test="$nodes">
+ <xsl:variable name="depth" select="count($nodes[1]/ancestor::*)"/>
+ <xsl:variable name="NEW_DEPTH">
+ <xsl:choose>
+ <xsl:when test="$depth > $DEPTH">
+ <xsl:value-of select="$depth"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$DEPTH"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:call-template name="max-depth2-aux">
+ <xsl:with-param name="nodes" select="$nodes[position() > 1]"/>
+ <xsl:with-param name="DEPTH" select="$NEW_DEPTH"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$DEPTH"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="max-depth2">
+ <xsl:call-template name="max-depth2-aux">
+ <xsl:with-param name="nodes" select="//node()[not(child::node())]"/>
+ </xsl:call-template>
+</xsl:template>
+
+</xsl:stylesheet>
+