Several report and keyword helper xsl files in admin section keywords
authorabraaksm
Wed, 23 Jul 2014 16:32:45 +0200
branchkeywords
changeset 520 58bfade9efbe
parent 519 d0dc387e89b6
child 521 7ec2c6d22adb
Several report and keyword helper xsl files in admin section
admin/report-output.xslt
admin/reports.xslt
report/report-keywords.xsl
report/report-testcases.xsl
report/report.xsl
report/resport-keywords.xsl
report/select-entrypoint.xsl
report/set-keywords.xsl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/admin/report-output.xslt	Wed Jul 23 16:32:45 2014 +0200
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
+    exclude-result-prefixes="xs math"
+    xpath-default-namespace="http://www.w3.org/2012/10/xslt-test-catalog"
+    version="3.0">
+    
+    <xsl:output method="xhtml" />
+    
+    <xsl:template match="/">
+        <html>
+            <head>
+                <title>Report XSLT test coverage</title>
+                <style type="text/css">
+                    * { font-family:Helvetica, Arial, Verdana, sans-serif; }
+                    h1 {font-size: 20pt; }
+                    table {border-collapse: collapse; border:1px solid black;}
+                    thead th {text-align: middle; border: 1px solid black }
+                    tbody th {text-align: left; border: 1px solid black; }
+                    
+                    td,
+                    th + th,
+                    td + th
+                    { 
+                        width: 60px; 
+                        border: 1px solid black;
+                        padding: 2px;
+                        text-align: right;
+                    }
+                    .head th { text-align: left } 
+                    th + th,
+                    td + th {
+                        border-right: none;
+                    }
+                    th + td,
+                    th + td + td {  
+                    border-left: none; 
+                    border-right: none 
+                    }
+                    th + td + td + td {  
+                        border-left: none; 
+                    }
+                    th + td + td + td + td + td { font-weight: bold; }
+                    th + td + td + td + td + td + td + td + td + td { font-weight: bold; }
+                </style>
+            </head>
+            <body>
+                <h1>Report XSLT test coverage</h1>
+                <div>
+                    <table>
+                        <thead>
+                            <tr class="head">
+                                <th>Name</th>
+                                <th colspan="4">XSLT 1.0</th>
+                                <th colspan="4">XSLT 2.0</th>
+                                <th colspan="4">XSLT 3.0</th>
+                                <th colspan="2">Unspecified</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <tr class="head" >
+                                <th>&#xA0;</th>
+                                <th>all</th>
+                                <th>spec</th>
+                                <th>back</th>
+                                <th>for</th>
+                                <th>all</th>
+                                <th>spec</th>
+                                <th>back</th>
+                                <th>for</th>
+                                <th>all</th>
+                                <th>spec</th>
+                                <th>back</th>
+                                <th>for</th>
+                                <th>nospec</th>
+                                <th>wrong</th>
+                            </tr>
+                            
+                            
+                            <xsl:apply-templates select="report/test-set" />
+                        </tbody>
+                    </table>
+                </div>
+            </body>
+        </html>
+    </xsl:template>
+    
+    <xsl:template match="test-set">
+        <tr>
+            <th>
+                <a href="{@uri}" title="{@description}">
+                    <xsl:value-of select="@name" />
+                </a>
+            </th>
+        
+            <xsl:apply-templates select="test-case-information/(xslt1 | xslt2 | xslt3 | other)" />
+        </tr>
+    </xsl:template>
+    
+    <xsl:template match="xslt1 | xslt2 | xslt3">
+        <th>
+            <xsl:value-of select="@count-total" />
+        </th>
+        <td>
+            <xsl:value-of select="@count-specific" />
+        </td>
+        <td>
+            <xsl:value-of select="@count-backward" />
+        </td>
+        <td>
+            <xsl:value-of select="@count-forward" />
+        </td>
+    </xsl:template>
+    
+    <xsl:template match="other">
+        <td>
+            <xsl:value-of select="@count-nospec" />
+        </td>
+        <td>
+            <xsl:value-of select="@count-wrongvalue" />
+        </td>
+    </xsl:template>
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/admin/reports.xslt	Wed Jul 23 16:32:45 2014 +0200
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns="http://www.w3.org/2012/10/xslt-test-catalog"
+    xpath-default-namespace="http://www.w3.org/2012/10/xslt-test-catalog"
+    version="3.0">
+    
+    <xsl:output indent="yes"/>
+    
+    <xsl:template match="/">
+        <report 
+            xmlns:xs="http://www.w3.org/2001/XMLSchema"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+            <xsl:apply-templates select="doc('../catalog.xml')" mode="catalog"/>
+        </report>
+    </xsl:template>
+    
+    <xsl:template match="/" mode="catalog">
+        <xsl:variable name="all">
+            <xsl:apply-templates select="catalog/test-set" mode="#current" />
+        </xsl:variable>
+        <xsl:apply-templates select="$all/test-set
+            [test-case-information[xslt3[@count-specific + @count-forward > 0]]]" mode="report"/>
+    </xsl:template>
+    
+    <xsl:template match="test-set" mode="report">
+         <xsl:copy-of select="." />
+    </xsl:template>
+    
+    
+    
+    <xsl:template match="test-set" mode="catalog">
+        <xsl:apply-templates select="doc(concat('../', @file))" mode="test-set" />
+    </xsl:template>
+    
+    <xsl:template match="/" mode="test-set">
+        <test-set name="{test-set/@name}" uri="{base-uri()}" description="{test-set/description}">
+            <test-case-information count="{count(test-set/test-case)}" >
+                <xslt1 count-total="{count(test-set/test-case/dependencies[spec[@value='XSLT10' or @value='XSLT10+']])}"
+                    count-specific="{count(test-set/test-case/dependencies[spec[@value='XSLT10']])}"
+                    count-backward="0"
+                    count-forward="{count(test-set/test-case/dependencies[spec[@value='XSLT10+']])}">
+                    
+                </xslt1>
+                <xslt2 count-total="{count(test-set/test-case/dependencies[spec[@value='XSLT20' or @value='XSLT20+' or @value='XSLT10+']])}"
+                    count-specific="{count(test-set/test-case/dependencies[spec[@value='XSLT20']])}"
+                    count-backward="{count(test-set/test-case/dependencies[spec[@value='XSLT10+']])}"
+                    count-forward="{count(test-set/test-case/dependencies[spec[@value='XSLT20+']])}">
+                    
+                </xslt2>
+                <xslt3 count-total="{count(test-set/test-case/dependencies[spec[@value='XSLT30' or @value='XSLT30+' or @value='XSLT20+' or @value='XSLT10+']])}" 
+                    count-specific="{count(test-set/test-case/dependencies[spec[@value='XSLT30']])}" 
+                    count-backward="{count(test-set/test-case/dependencies[spec[@value='XSLT20+' or @value='XSLT10+']])}" 
+                    count-forward="{count(test-set/test-case/dependencies[spec[@value='XSLT30+']])}">
+                    <coverage>
+                        <xsl:variable name="xsl-elements">
+                            <xsl:apply-templates select="test-set/test-case[1]/test/stylesheet/@file" mode="#current" />
+                        </xsl:variable>
+                        <xsl:for-each select="distinct-values($xsl-elements/xsl-elements/@found/tokenize(., ' '))">
+                            <element name="xsl:{.}" count="{count($xsl-elements/xsl-elements[contains(@found, current())])}" />
+                        </xsl:for-each>                        
+                    </coverage>
+                </xslt3>
+                <other count-nospec="{count(test-set/test-case/dependencies[not(spec)])}" 
+                    count-wrongvalue="{count(test-set/test-case/dependencies[spec[not(starts-with(@value,'XSLT3') or starts-with(@value,'XSLT2') or starts-with(@value,'XSLT1'))]])}" />
+                    
+            </test-case-information>
+        </test-set>
+    </xsl:template>
+    
+    <xsl:template match="@file" mode="test-set">
+        <xsl:variable name="base-path" select="replace(base-uri(.), '[^/]+$', '')" />
+       <xsl:try>
+           <xsl:apply-templates select="doc(concat($base-path, .))" mode="test-xslfile" />
+           <xsl:catch>
+               <xsl-elements error-in-file="{concat($base-path, .)}" error="" />
+           </xsl:catch>
+       </xsl:try>
+    </xsl:template>
+    
+    <xsl:template match="/" mode="test-xslfile">
+        <xsl-elements found="{distinct-values(//xsl:*/local-name())}" />
+    </xsl:template>
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/report/report-keywords.xsl	Wed Jul 23 16:32:45 2014 +0200
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns:math="http://www.w3.org/2005/xpath-functions/math" 
+    xmlns:f="http://exselt.net/local"
+    xmlns="http://www.w3.org/2012/10/xslt-test-catalog" 
+    exclude-result-prefixes="xs f math"
+    xpath-default-namespace="http://www.w3.org/2012/10/xslt-test-catalog" 
+    version="3.0">
+
+    <xsl:output indent="yes"/>
+
+    <!-- provide a test location base-uri with a trailing slash -->
+    <xsl:param name="test-location" select="'file:///d:/projects/w3.org/xt3/'"/>
+    <xsl:param name="is-saxon" select="system-property('xsl:vendor') = 'Saxonica'" static="yes" />
+    
+    <xsl:mode name="catalog" on-no-match="shallow-skip"/>
+    <xsl:mode name="test-set" on-no-match="shallow-skip"/>
+    <xsl:mode name="keywords" on-no-match="shallow-copy"/>
+
+    <xsl:variable name="test-catalog" select="resolve-uri('catalog.xml', $test-location)"/>
+
+    <xsl:template match="/" use-when="$is-saxon">
+        <xsl:call-template name="main" />
+    </xsl:template>
+    
+    <xsl:template name="xsl:initial-template" use-when="not($is-saxon)">
+        <xsl:call-template name="main" />
+    </xsl:template>
+    
+
+    <xsl:template name="main">
+        <xsl:variable name="keywords" as="element()*">
+            <xsl:apply-templates select="doc($test-catalog)" mode="catalog"/>
+        </xsl:variable>
+        <xsl:variable name="sorted-keywords" as="element()*">
+            <xsl:apply-templates select="$keywords" mode="keywords">
+                <xsl:sort/>
+            </xsl:apply-templates>
+        </xsl:variable>
+
+        <keywords>
+            <xsl:for-each-group select="$sorted-keywords" group-adjacent="string(.)">
+                <xsl:copy>
+                    <xsl:attribute name="belongs-to" select="current-group()/@belongs-to"/>
+                    <xsl:attribute name="count" select="count(current-group())"/>
+                    <xsl:attribute name="value" select="current-group()[1]/string(.)"/>
+                </xsl:copy>
+            </xsl:for-each-group>
+        </keywords>
+    </xsl:template>
+
+    <xsl:template match="test-set" mode="catalog">
+        <xsl:apply-templates select="doc(resolve-uri(@file, $test-location))" mode="test-set"/>
+    </xsl:template>
+
+    <xsl:template match="keywords" mode="test-set">
+        <xsl:apply-templates select="tokenize(., ' ')" mode="#current">
+            <xsl:with-param name="node" select=".." />
+        </xsl:apply-templates>
+    </xsl:template>
+
+    <xsl:template match=".[. instance of xs:string]" mode="test-set">
+        <xsl:param name="node" as="node()?"/>
+        <keyword belongs-to="{$node/@name}">
+            <xsl:value-of select="."/>
+        </keyword>
+    </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/report/report-testcases.xsl	Wed Jul 23 16:32:45 2014 +0200
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
+    xmlns:f="http://exselt.net/local"
+    xmlns="http://www.w3.org/2012/10/xslt-test-catalog"
+    exclude-result-prefixes="xs f math"
+    xpath-default-namespace="http://www.w3.org/2012/10/xslt-test-catalog"
+    version="3.0">
+    
+    <xsl:output indent="yes" />
+    
+    <!-- provide a test location base-uri with a trailing slash -->
+    <xsl:param name="test-location" select="'file:///d:/projects/w3.org/xt3/'" />
+    
+    <xsl:mode name="catalog" on-no-match="shallow-skip" />
+    <xsl:mode name="test-set" on-no-match="shallow-skip" />
+    <xsl:mode name="keywords" on-no-match="shallow-copy" />
+    
+    <xsl:variable name="test-catalog" select="resolve-uri('catalog.xml', $test-location)" />
+    
+    <xsl:template name="xsl:initial-template" match="/">
+        <xsl:variable name="test-cases" as="element()*">
+            <xsl:apply-templates select="doc($test-catalog)" mode="catalog" />
+        </xsl:variable>
+        
+        <test-cases>
+            <!-- names are unique, no need to check for dups -->
+            <xsl:for-each select="$test-cases" >
+                <xsl:sort />
+                <xsl:copy-of select="."/>
+            </xsl:for-each>
+        </test-cases>
+    </xsl:template>
+    
+    <xsl:template match="test-set" mode="catalog">
+        <xsl:apply-templates select="doc(resolve-uri(@file, $test-location))" mode="test-set" />
+    </xsl:template>
+    
+    <xsl:template match="test-case" mode="test-set">
+        <xsl:copy copy-namespaces="no">
+            <xsl:value-of select="@name" />
+        </xsl:copy>
+    </xsl:template>
+    
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/report/report.xsl	Wed Jul 23 16:32:45 2014 +0200
@@ -0,0 +1,378 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns:math="http://www.w3.org/2005/xpath-functions/math" xmlns:f="http://myfunction"
+    xmlns:q="http://www.w3.org/2014/05/test-report" xmlns:saxon="http://saxon.sf.net/"
+    exclude-result-prefixes="xs math f"
+    xpath-default-namespace="http://www.w3.org/2012/10/xslt-test-catalog" version="3.0">
+
+    <xsl:mode name="cat" on-no-match="shallow-skip"/>
+    <xsl:mode name="cat-set" on-no-match="shallow-skip"/>
+    <xsl:mode name="query" on-no-match="shallow-skip"/>
+
+    <xsl:output indent="yes" saxon:line-length="200"
+        saxon:attribute-order="name total-count soft-count description instruction"/>
+
+    <xsl:param name="testlocation" select="'file:///D:/Projects/W3.org/XT3'"/>
+
+    <xsl:param name="testcat" select="$testlocation || '/catalog.xml'"/>
+
+    <xsl:variable name="queries" as="element()*">
+        <!-- attr -->
+        <q:set name="as" description="Type requirements (as-attribute)" by-attribute="as">
+            <q:query group-by="parent-name"/>
+        </q:set>
+
+        <q:query setname="avt" name="Attribute value templates">//@*[contains(., '{') or contains(.,
+            '}')]</q:query>
+
+        <q:set name="expand-text" description="CVT expand-text" by-attribute="expand-text">
+            <q:query group-by="parent-name"/>
+        </q:set>
+        <q:set name="match" description="Matching templates" by-attribute="match">
+            <q:query group-by="parent-name"/>
+        </q:set>
+
+        <q:set name="mode" description="Modes (XSLT 2.0)" by-attribute="mode">
+            <q:query group-by="parent-name"/>
+        </q:set>
+        <q:set name="select" description="Select attribute" by-attribute="select">
+            <q:query group-by="parent-name"/>
+        </q:set>
+        <q:set name="select" description="Separator attribute" by-attribute="separator">
+            <q:query group-by="parent-name"/>
+        </q:set>
+        <q:set name="streamable" description="Streamable attribute" by-attribute="streamable">
+            <q:query group-by="parent-name"/>
+        </q:set>
+        <q:set name="strip-type-annotations" description="Strip type annotations"
+            by-attribute="input-type-annotations">
+            <q:query group-by="parent-name"/>
+        </q:set>
+        <q:set name="tunnel" description="Tunnel parameters" by-attribute="tunnel">
+            <q:query group-by="parent-name"/>
+        </q:set>
+        <q:set name="use-when" description="use-when attribute" by-attribute="use-when">
+            <q:query group-by="parent-name"/>
+        </q:set>
+        <q:set name="validation" description="Validation attribute" by-attribute="validation">
+            <q:query group-by="parent-name"/>
+        </q:set>
+        <q:set name="version" description="Version attribute" by-attribute="version">
+            <q:query group-by="parent-name"/>
+        </q:set>
+        <q:set name="xpath-default-namespace" description="XPath default namespace attribute"
+            by-attribute="xpath-default-namespace">
+            <q:query group-by="parent-name"/>
+        </q:set>
+
+        <!-- streaming functions -->
+        <q:set name="sf-avg" description="Streaming: averaging" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-boolean" description="Streaming: boolean" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-outermost" description="Streaming: outermost" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-one-or-more" description="Streaming: one-or-more" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-reverse" description="Streaming: reverse function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-codepoints-to-string" description="Streaming: codepoints-to-string function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-count" description="Streaming: count function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-deep-equal" description="Streaming: deep-equal function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-distinct-values" description="Streaming: distinct-values function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-empty" description="Streaming: empty function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-exactly-one" description="Streaming: exactly-one function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-exists" description="Streaming: exists function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-filter" description="Streaming: filter function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-fold-left" description="Streaming: fold-left function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-fold-right" description="Streaming: fold-right function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-head" description="Streaming: head function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-index-of" description="Streaming: index-of function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-innermost" description="Streaming: innermost function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-insert-before" description="Streaming: insert-before function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-map-new" description="Streaming: map-new function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-max" description="Streaming: max function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-min" description="Streaming: min function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-not" description="Streaming: not function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-one-or-more" description="Streaming: one-or-more function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-outermost" description="Streaming: outermost function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-remove" description="Streaming: remove function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-string-join" description="Streaming: string-join function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-subsequence" description="Streaming: subsequence function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-sum" description="Streaming: sum function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-tail" description="Streaming: tail function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-trace" description="Streaming: trace function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-unordered" description="Streaming: unordered function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="sf-zero-or-one" description="Streaming: zero-or-one function" by-instruction="stream">
+            <q:query group-by="function" />
+        </q:set>
+        
+        <!-- declarations -->
+        <q:set name="accumulator" description="Declaration xsl:accumulator (XSLT 3.0)"
+            by-instruction="accumulator">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="attribute-set" description="Declaration xsl:attribute-set"
+            by-instruction="attribute-set">
+            <q:query group-by="function" />
+        </q:set>
+        <q:set name="character-map" description="Declaration xsl:character-map"
+            by-instruction="character-map"/>
+        <q:set name="function" description="Declaration xsl:function" by-instruction="function"/>
+        <q:set name="import" description="Declaration xsl:import" by-instruction="import"/>
+        <q:set name="import-schema" description="Declaration xsl:import-schema"
+            by-instruction="import-schema"/>
+        <q:set name="include" description="Declaration xsl:include" by-instruction="include"/>
+        <q:set name="mode" description="Declaration xsl:mode (XSLT 3.0)" by-instruction="mode"/>
+        <q:set name="namespace-alias" description="Declaration xsl:namespace-alias"
+            by-instruction="namespace-alias"/>
+        <q:set name="output" description="Declaration xsl:output" by-instruction="output"/>
+        <q:set name="override" description="Declaration xsl:override (XSLT 3.0)"
+            by-instruction="override"/>
+        <q:set name="package" description="Declaration xsl:package (XSLT 3.0)"
+            by-instruction="package"/>
+        <q:set name="param" description="Declaration xsl:param" by-instruction="param"/>
+        <q:set name="template" description="Declaration xsl:template" by-instruction="template"/>
+        <q:set name="use-package" description="Declaration xsl:use-package (XSLT 3.0)"
+            by-instruction="use-package"/>
+        <q:set name="variable" description="Declaration xsl:variable" by-instruction="variable"/>
+
+        <!-- instructions -->
+        <q:set name="analyze-string" description="Instruction xsl:analyze-string"
+            by-instruction="analyze-string"/>
+        <q:set name="apply-templates" description="Instruction xsl:apply-templates"
+            by-instruction="apply-templates"/>
+        <q:set name="assert" description="Instruction xsl:assert" by-instruction="assert"/>
+        <q:set name="attribute" description="Instruction xsl:attribute" by-instruction="attribute"/>
+        <q:set name="call-template" description="Instruction xsl:call-template"
+            by-instruction="call-template"/>
+        <q:set name="choose" description="Instruction xsl:choose" by-instruction="choose"/>
+        <q:set name="construct-node" description="Node construction" by-lre="true"/>
+        <q:set name="copy" description="Instruction xsl:copy" by-instruction="copy"/>
+        <q:set name="element" description="Instruction xsl:element" by-instruction="element"/>
+        <q:set name="evaluate" description="Instruction xsl:evaluate" by-instruction="evaluate"/>
+        <q:set name="for-each-group" description="Instruction xsl:for-each-group"
+            by-instruction="for-each-group"/>
+        <!--q:set name="iterate" description="Instruction xsl:iterate" by-instruction="iterate"/-->
+        <q:set name="lre" description="Literal result elements" by-lre="true"/>
+        <q:set name="merge" description="Instruction xsl:merge" by-instruction="merge"/>
+        <q:set name="message" description="Instruction xsl:message" by-instruction="message"/>
+        <q:set name="next-match" description="Instruction xsl:next-match"
+            by-instruction="next-match"/>
+        <q:set name="number" description="Instruction xsl:number" by-instruction="number"/>
+        <q:set name="result-document" description="Instruction xsl:result-document"
+            by-instruction="result-document"/>
+        <q:set name="sequence" description="Instruction xsl:sequence" by-instruction="sequence"/>
+        <q:set name="sort" description="Instruction xsl:sort" by-instruction="sort"/>
+        <q:set name="stream" description="Instruction xsl:stream" by-instruction="stream"/>
+        <q:set name="try" description="Instruction xsl:try" by-instruction="try"/>
+        <q:set name="xsl-document" description="Instruction xsl:document" by-instruction="document"
+        />
+    </xsl:variable>
+
+    <xsl:template match="/">
+        <xsl:apply-templates select="doc($testcat)" mode="cat"/>
+    </xsl:template>
+
+    <xsl:template match="*" mode="cat">
+        <report>
+            <xsl:apply-templates mode="#current"/>
+        </report>
+    </xsl:template>
+
+    <!-- start processing test set -->
+    <xsl:template match="test-set" mode="cat">
+        <xsl:apply-templates select="doc($testlocation || '/' || @file)" mode="cat-set"/>
+    </xsl:template>
+
+    <xsl:template match="test-set" mode="cat-set">
+        <xsl:variable name="tests" as="element()">
+            <tests category="{/*/@name}">
+                <xsl:attribute name="xsluris">
+                    <xsl:value-of
+                        select="test-case/test/stylesheet/@file/string(resolve-uri(., base-uri(.))),
+                        environment/stylesheet/@file/string(resolve-uri(., base-uri(.)))"
+                    />
+                </xsl:attribute>
+                <xsl:attribute name="total-count" select="count(test-case)"/>
+            </tests>
+        </xsl:variable>
+
+        <xsl:apply-templates select="$queries" mode="query">
+            <xsl:with-param name="tests" select="$tests"/>
+        </xsl:apply-templates>
+    </xsl:template>
+
+    <xsl:template match="q:set[@by-attribute]" mode="query">
+        <xsl:param name="tests"/>
+        <xsl:variable name="set" select="."/>
+
+        <!-- count query in each xsl document -->
+        <xsl:variable name="countseq" as="xs:integer*"
+            select="count(f:getdocs($tests, $set)//*[f:query-by-attrib(., current())])"/>
+
+        <xsl:if test="sum($countseq) gt 0">
+            <category attribute="{@by-attribute}" total-count="{$tests/@total-count}">
+                <xsl:attribute name="name" select="@name"/>
+                <xsl:copy-of select="@description"/>
+                <xsl:attribute name="soft-count" select="sum($countseq)"/>
+
+                <xsl:apply-templates mode="#current">
+                    <xsl:with-param name="tests" select="$tests"/>
+                </xsl:apply-templates>
+            </category>
+        </xsl:if>
+    </xsl:template>
+
+
+    <xsl:template match="q:set[@by-instruction]" mode="query">
+        <xsl:param name="tests"/>
+        <xsl:variable name="set" select="."/>
+
+        <!-- count query in each xsl document -->
+        <xsl:variable name="countseq" as="xs:integer*"
+            select="count(f:getdocs($tests, $set)//*[f:query-by-instruction(., current())])"/>
+
+        <xsl:if test="sum($countseq) gt 0">
+            <category instruction="{@by-instruction}" total-count="{$tests/@total-count}">
+                <xsl:attribute name="name" select="@name"/>
+                <xsl:copy-of select="@description"/>
+                <xsl:attribute name="soft-count" select="sum($countseq)"/>
+                <xsl:apply-templates mode="#current">
+                    <xsl:with-param name="tests" select="$tests"/>
+                </xsl:apply-templates>
+            </category>
+        </xsl:if>
+    </xsl:template>
+
+    <xsl:template match="q:query[@group-by='parent-name']" mode="query">
+        <xsl:param name="tests"/>
+        <xsl:variable name="q-set" select="current()/.."/>
+        <xsl:variable name="xsldocs" select="f:getdocs($tests, current()/..)"/>
+        <xsl:variable name="instructions"
+            select="
+            for $doc in $xsldocs 
+            return $doc//*[f:query-by-attrib(., $q-set)]
+                /QName(namespace-uri(.), local-name(.))"/>
+
+        <!-- count per instruction -->
+        <xsl:for-each
+            select="distinct-values($instructions[namespace-uri-from-QName(.) = 'http://www.w3.org/1999/XSL/Transform'])">
+            <instruction name="xsl:{.}">
+                <xsl:attribute name="soft-count"
+                    select="count($xsldocs//*[local-name() = local-name-from-QName(current())][f:query-by-attrib(., $q-set)])"
+                />
+            </instruction>
+        </xsl:for-each>
+
+        <!-- count per LRE -->
+        <xsl:for-each select="distinct-values($instructions[namespace-uri-from-QName(.) = ''])">
+            <literal-result-element name="{.}">
+                <xsl:attribute name="soft-count"
+                    select="count($xsldocs//*[local-name() = local-name-from-QName(current())][f:query-by-attrib(., $q-set)])"
+                />
+            </literal-result-element>
+        </xsl:for-each>
+    </xsl:template>
+
+    <xsl:template match="q:query[@group-by='function']" mode="query">
+        <xsl:param name="tests"/>
+        <xsl:variable name="q-set" select="current()/.."/>
+        <xsl:variable name="xsldocs" select="f:getdocs($tests, current()/..)"/>
+
+        <xsl:variable name="function-names" as="xs:string*">
+            <xsl:for-each select="$xsldocs//@*">
+                <xsl:analyze-string select="." regex="([-a-z0-9:]+ *)\(">
+                    <xsl:matching-substring>
+                        <xsl:sequence select="regex-group(1)"/>
+                    </xsl:matching-substring>
+                </xsl:analyze-string>
+            </xsl:for-each>
+        </xsl:variable>
+
+        <!-- count per instruction -->
+        <xsl:for-each select="distinct-values($function-names)">
+            <function name="{.}" soft-count="{count($function-names[. = current()])}" />
+        </xsl:for-each>
+    </xsl:template>
+
+    <xsl:function name="f:getdocs" as="document-node()*">
+        <xsl:param name="tests"/>
+        <xsl:param name="set"/>
+        <xsl:copy-of select="document(tokenize($tests/@category[. = $set/@name]/../@xsluris, ' '))"
+        />
+    </xsl:function>
+
+    <xsl:function name="f:query-by-attrib" as="xs:boolean">
+        <xsl:param name="n"/>
+        <xsl:param name="q-set"/>
+        <xsl:sequence select="not(empty($n[@*[local-name() = $q-set/@by-attribute]]))"/>
+    </xsl:function>
+
+    <xsl:function name="f:query-by-instruction" as="xs:boolean">
+        <xsl:param name="n"/>
+        <xsl:param name="q-set"/>
+        <xsl:sequence select="not(empty($n[self::*[local-name() = $q-set/@by-instruction]]))"/>
+    </xsl:function>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/report/resport-keywords.xsl	Wed Jul 23 16:32:45 2014 +0200
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
+    xmlns:f="http://exselt.net/local"
+    xmlns="http://www.w3.org/2012/10/xslt-test-catalog"
+    exclude-result-prefixes="xs f math"
+    xpath-default-namespace="http://www.w3.org/2012/10/xslt-test-catalog"
+    version="3.0">
+    
+    <xsl:output indent="yes" />
+    
+    <!-- provide a test location base-uri with a trailing slash -->
+    <xsl:param name="test-location" select="'file:///d:/projects/w3.org/xt3/'" />
+    
+    <xsl:mode name="catalog" on-no-match="shallow-skip" />
+    <xsl:mode name="test-set" on-no-match="shallow-skip" />
+    <xsl:mode name="keywords" on-no-match="shallow-copy" />
+    
+    <xsl:variable name="test-catalog" select="resolve-uri('catalog.xml', $test-location)" />
+    
+    <xsl:template name="xsl:initial-template" match="/">
+        <xsl:variable name="keywords" as="element()*">
+            <xsl:apply-templates select="doc($test-catalog)" mode="catalog" />
+        </xsl:variable>
+        <xsl:variable name="sorted-keywords" as="element()*">
+            <xsl:apply-templates select="$keywords" mode="keywords">
+                <xsl:sort />
+            </xsl:apply-templates>
+        </xsl:variable>
+        
+        <keywords>
+            <xsl:for-each-group select="$sorted-keywords" group-adjacent="string(.)">
+               <keyword>
+                  <xsl:attribute name="count" select="count(current-group())" namespace=""/>
+                  <xsl:attribute name="value" select="current-group()[1]/string(.)"  namespace=""/>
+               </keyword>
+            </xsl:for-each-group>
+        </keywords>
+    </xsl:template>
+    
+    <xsl:template match="test-set" mode="catalog">
+        <xsl:apply-templates select="doc(resolve-uri(@file, $test-location))" mode="test-set" />
+    </xsl:template>
+    
+    <xsl:template match="keywords" mode="test-set">
+        <xsl:apply-templates select="tokenize(., ' ')" mode="#current" />
+    </xsl:template>
+    
+    <xsl:template match=".[. instance of xs:string]" mode="test-set">
+        <keyword><xsl:value-of select="." /></keyword>
+    </xsl:template>
+    
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/report/select-entrypoint.xsl	Wed Jul 23 16:32:45 2014 +0200
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
+    xmlns:f="http://exselt.net/local"
+    xmlns="http://www.w3.org/2012/10/xslt-test-catalog"
+    exclude-result-prefixes="xs f math"
+    xpath-default-namespace="http://www.w3.org/2012/10/xslt-test-catalog"
+    version="3.0">
+    
+    <xsl:import href="_report-package.xsl" />
+    
+    <xsl:output indent="no" />
+    
+    <!-- provide a test location base-uri with a trailing slash -->
+    <xsl:param name="test-location" select="'file:///d:/projects/w3.org/xt3/'" />
+    <xsl:param name="test-set" select="'mode'" />
+    <xsl:param name="test-case" select="'mode-0001'" />
+    <xsl:param name="show-full-xslt" select="'true'" />
+    <xsl:param name="is-saxon" select="system-property('xsl:vendor') = 'Saxonica'" static="yes" />
+    
+    <xsl:mode name="catalog" on-no-match="shallow-skip" />
+    <xsl:mode name="test-set" on-no-match="shallow-skip" />
+    <xsl:mode name="xsl" on-no-match="shallow-copy" />
+    <xsl:mode name="keywords" on-no-match="shallow-skip" />
+    
+    <xsl:variable name="test-catalog" select="resolve-uri('catalog.xml', $test-location)" />
+    
+    <xsl:variable name="keyword-hints-input" select="resolve-uri('keyword-hints.xml', static-base-uri())" />
+    
+    <xsl:template match="/" use-when="$is-saxon">
+        <xsl:call-template name="main" />
+    </xsl:template>
+    
+    <xsl:template name="xsl:initial-template" use-when="not($is-saxon)">
+        <xsl:call-template name="main" />
+    </xsl:template>
+    
+    <xsl:template name="main">
+        <xsl:text>&#xA;</xsl:text>
+        
+        <xsl:variable name="entrypoint">
+            <xsl:apply-templates select="doc($test-catalog)" mode="catalog" />
+        </xsl:variable>
+        
+        <result>
+            <xsl:attribute name="keyword-hints" use-when="true()">
+                <xsl:apply-templates select="document($keyword-hints-input)" mode="keywords">
+                    <xsl:with-param name="entrypoint" select="$entrypoint" tunnel="yes" />
+                </xsl:apply-templates>                
+            </xsl:attribute>
+            <xsl:text>&#xA;</xsl:text>
+            <xsl:copy-of select="$entrypoint" />
+        </result>
+    </xsl:template>
+    
+    <xsl:template match="document-node()" mode="keywords" xpath-default-namespace="">
+        <xsl:variable name="keyword-hints">
+            <xsl:apply-templates select="*/hint[not(@active eq 'no')]" mode="#current" />        
+        </xsl:variable>
+        <xsl:variable name="filtered-keyword-hints">
+            <xsl:apply-templates select="$keyword-hints/tokenize(., ' ')" mode="filter-keywords" >
+                <xsl:with-param name="filter" select="*/filter" tunnel="yes" />
+                <xsl:with-param name="all-keywords" select="$keyword-hints" tunnel="yes" />
+            </xsl:apply-templates>
+        </xsl:variable>
+        <xsl:value-of select="$filtered-keyword-hints" separator=" " />
+    </xsl:template>
+    
+    <!-- removes keywords if a certain other keyword is already there -->
+    <xsl:template match="." mode="filter-keywords" xpath-default-namespace="">
+        <xsl:param name="filter" tunnel="yes" />
+        <xsl:param name="all-keywords" tunnel="yes" />
+        <xsl:variable name="if-keywords" select="$filter/if-keyword[. = $all-keywords/tokenize(., ' ')]" />
+        <xsl:variable name="remove-keywords" select="$if-keywords/following-sibling::remove-keywords/tokenize(., ' ')" />
+        <xsl:sequence select=".[not(. = $remove-keywords)]" />
+    </xsl:template>
+
+    
+    <!-- find keyword hints based on keyword-hints.xml -->
+    <xsl:template match="hint" mode="keywords" xpath-default-namespace="">
+        <xsl:param name="entrypoint" required="yes" tunnel="yes" />
+        <xsl:variable name="matches-xpath" as="xs:boolean">
+            <xsl:evaluate xpath="'not(empty(' || xpath || '))'" context-item="$entrypoint" />
+        </xsl:variable>
+
+        <xsl:if test="$matches-xpath">
+            <xsl:sequence select="keywords/text()/string()" />
+        </xsl:if>
+    </xsl:template>
+    
+    <xsl:template match="hint[keywords[@as-xpath eq 'yes']]" mode="keywords" xpath-default-namespace="">
+        <xsl:param name="entrypoint" required="yes" tunnel="yes" />
+        <xsl:variable name="matches-xpath" as="xs:boolean">
+            <xsl:evaluate xpath="'not(empty(' || xpath || '))'" context-item="$entrypoint" />
+        </xsl:variable>
+        
+        <xsl:if test="$matches-xpath">
+            <xsl:sequence>
+                <xsl:evaluate xpath="keywords/text()" context-item="$entrypoint" />
+            </xsl:sequence>
+        </xsl:if>
+    </xsl:template>
+    
+    
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/report/set-keywords.xsl	Wed Jul 23 16:32:45 2014 +0200
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
+    xmlns:f="http://exselt.net/local"
+    xmlns="http://www.w3.org/2012/10/xslt-test-catalog"
+    exclude-result-prefixes="xs f math"
+    xpath-default-namespace="http://www.w3.org/2012/10/xslt-test-catalog"
+    version="3.0">
+    
+    <xsl:output indent="no" cdata-section-elements="content assert-xml" />
+    
+    <!-- provide a test location base-uri with a trailing slash -->
+    <xsl:param name="test-location" select="'file:///d:/projects/w3.org/xt3/'" />
+    <xsl:param name="test-set" select="'as'" />
+    <xsl:param name="test-case" select="'as-0114'" />
+    <xsl:param name="test-keywords" select="'testttt'" />
+    
+
+    <xsl:param name="is-saxon" select="system-property('xsl:vendor') = 'Saxonica'" static="yes" />
+    
+    <xsl:mode name="catalog" on-no-match="shallow-skip" />
+    <xsl:mode name="test-set" on-no-match="shallow-copy" />
+    
+    <xsl:variable name="test-catalog" select="resolve-uri('catalog.xml', $test-location)" />
+    
+    <xsl:template match="/" use-when="$is-saxon">
+        <xsl:text>&#xA;</xsl:text>
+        <xsl:apply-templates select="doc($test-catalog)" mode="catalog" />
+    </xsl:template>
+    
+    <xsl:template name="xsl:initial-template" use-when="not($is-saxon)">
+        <xsl:text>&#xA;</xsl:text>
+        <xsl:apply-templates select="doc($test-catalog)" mode="catalog" />
+    </xsl:template>
+    
+    <xsl:template match="test-set[@name = $test-set]" mode="catalog">        
+        <xsl:apply-templates select="doc(resolve-uri(@file, $test-location))" mode="test-set" />
+    </xsl:template>
+    
+    <!-- missing keyword, insert <keywords> after <description> and leave indentation intact -->
+    <xsl:template match="test-case[@name = $test-case][not(keywords)]" mode="test-set">
+        <xsl:copy>
+            <xsl:apply-templates select="@*" mode="#current" />
+            <!-- non-element nodes before <description> -->
+            <xsl:apply-templates select="node()[current()/description >> .]" mode="#current" />
+            <xsl:apply-templates select="description" mode="#current" />
+            <!-- non-element nodes after description but before the next element -->
+            <xsl:apply-templates select="description/following-sibling::node()[current()/description/following-sibling::*[1] >> .]" mode="#current" />
+            
+            <!-- BUG in Saxon (I think), it copies the xs-namespace into <keywords> ... -->
+            <keywords><xsl:value-of select="$test-keywords" /></keywords>
+            
+            <!-- copy text node for LF and indentation -->
+            <xsl:copy-of select="text()[1]" />
+            
+            <!-- everything after <description> element -->
+            <xsl:apply-templates select="text()[2]/following-sibling::node()" mode="#current" />
+        </xsl:copy>
+    </xsl:template>
+    
+    <!-- test-case with keywords, just update the keywords -->
+    <xsl:template match="test-case[@name = $test-case]/keywords" mode="test-set">
+        <xsl:copy>
+            <xsl:value-of select="$test-keywords" />
+        </xsl:copy>
+    </xsl:template>
+    
+</xsl:stylesheet>
\ No newline at end of file