<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:its="http://www.w3.org/2005/11/its"
                xmlns:datc="http://example.com/datacats"
                version="2.0">
   <xsl:output method="xml" indent="yes" encoding="utf-8"/>
   <xsl:strip-space elements="*"/>
   <xsl:template match="*|@*" mode="get-full-path">
      <xsl:apply-templates select="parent::*" mode="get-full-path"/>
      <xsl:text>/</xsl:text>
      <xsl:if test="count(. | ../@*) = count(../@*)">@</xsl:if>
      <xsl:value-of select="concat('{', namespace-uri(.),'}',local-name())"/>
      <xsl:if test="self::element() and parent::element()">
         <xsl:text>[</xsl:text>
         <xsl:number/>
         <xsl:text>]</xsl:text>
      </xsl:if>
   </xsl:template>
   <xsl:template name="writeOutput">
      <xsl:param name="outputType">no-value</xsl:param>
      <xsl:param name="outputValue" as="node()*">
         <output>no-value</output>
      </xsl:param>
      <xsl:element name="node">
         <xsl:attribute name="path">
            <xsl:apply-templates mode="get-full-path" select="."/>
         </xsl:attribute>
         <xsl:attribute name="outputType">
            <xsl:value-of select="$outputType"/>
         </xsl:attribute>
         <xsl:copy-of select="$outputValue"/>
      </xsl:element>
   </xsl:template>
   <xsl:template match="/">
      <nodeList>
         <xsl:element name="nodeList">
            <xsl:attribute name="datacat">
               <xsl:text>terminology</xsl:text>
            </xsl:attribute>
            <xsl:apply-templates mode="terminology">
               <xsl:with-param name="existingDataCatValue">default-value</xsl:with-param>
            </xsl:apply-templates>
         </xsl:element>
      </nodeList>
   </xsl:template>
   <xsl:template match="*[@its:term] | its:span[@term]" mode="terminology" priority="+1000">
      <xsl:call-template name="writeOutput">
         <xsl:with-param name="outputType">new-value-local</xsl:with-param>
         <xsl:with-param name="outputValue" as="node()*">
            <output>
               <xsl:for-each select="@its:term | @term[parent::its:span or parent::its:termRule] | @its:termInfoRef | @termInfoRef[parent::its:span]">
                  <xsl:copy-of select="."/>
               </xsl:for-each>
            </output>
         </xsl:with-param>
      </xsl:call-template>
      <xsl:apply-templates mode="terminology" select="@* | element()">
         <xsl:with-param name="existingDataCatValue" as="node()*">default-value</xsl:with-param>
      </xsl:apply-templates>
   </xsl:template>
   <xsl:template match="*" mode="terminology" priority="-1000">
      <xsl:param name="existingDataCatValue" as="node()*">no-value</xsl:param>
      <xsl:if test="$existingDataCatValue='default-value'">
         <xsl:call-template name="writeOutput">
            <xsl:with-param name="outputType">default-value</xsl:with-param>
            <xsl:with-param name="outputValue" as="node()*">
               <output its:term="no"/>
            </xsl:with-param>
         </xsl:call-template>
         <xsl:apply-templates mode="terminology" select="@* | element()">
            <xsl:with-param name="existingDataCatValue" as="node()*">default-value</xsl:with-param>
         </xsl:apply-templates>
      </xsl:if>
      <xsl:if test="$existingDataCatValue='no-value'">
         <xsl:call-template name="writeOutput">
            <xsl:with-param name="outputType">no-value</xsl:with-param>
            <xsl:with-param name="outputValue" as="node()*">
               <output/>
            </xsl:with-param>
         </xsl:call-template>
         <xsl:apply-templates mode="terminology" select="@* | element()">
            <xsl:with-param name="existingDataCatValue" as="node()*">no-value</xsl:with-param>
         </xsl:apply-templates>
      </xsl:if>
   </xsl:template>
   <xsl:template match="@*" mode="terminology" priority="-1000">
      <xsl:param name="existingDataCatValue" as="node()*">no-value</xsl:param>
      <xsl:call-template name="writeOutput">
         <xsl:with-param name="outputType">default-value</xsl:with-param>
         <xsl:with-param name="outputValue" as="node()*">
            <output its:term="no"/>
         </xsl:with-param>
      </xsl:call-template>
   </xsl:template>
</xsl:stylesheet>