<xsl:stylesheet xmlns:attr="http://www.xstandoff.net/2009/functions/attr" xmlns:bool="http://www.xstandoff.net/2009/functions/bool" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:double="http://www.xstandoff.net/2009/functions/double" xmlns:saxon="http://saxon.sf.net/" xmlns:all="http://www.xstandoff.net/2009/all" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xd="http://www.pnp-software.com/XSLTdoc" xmlns:xsf="http://www.xstandoff.net/2009/xstandoff/1.1" xmlns:int="http://www.xstandoff.net/2009/functions/integer" xmlns:string="http://www.xstandoff.net/2009/functions/string" xmlns="http://www.xstandoff.net/2009/xstandoff/1.1" xmlns:undef="http://www.xstandoff.net/2009/functions/undef" xmlns:elem="http://www.xstandoff.net/2009/functions/elem" version="2.0" extension-element-prefixes="saxon" exclude-result-prefixes="string undef elem attr bool double xs int all xsf saxon xd">

    

    
<!-- ############ STYLESHEET DOCUMENTATION ##########-->

    
         <xd:doc type="stylesheet">

        
<xd:author>Daniel Jettka; daniel.jettka@uni-bielefeld.de; Project Sekimo (A2); DFG Research Group 437</xd:author>

        
<xd:copyright>GNU Lesser General Public License, see below for details</xd:copyright>

        
<xd:short><p><b>inline2XSF.xsl - Transformation of inline annotations to XSF</b></p></xd:short>

        
<xd:detail>

            
<p><b>Version 17.02.2011, 15:39 (GMT)</b></p>

            
<p>This program is free software: you can redistribute it and/or modify it under the terms of the GNU GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.</p>

            
<p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU GNU Lesser General Public License for more details.</p>

            
<p>You should have received a copy of the GNU GNU Lesser General Public License along with this program (file 'lgpl-3.0.txt').  If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>

            
<p>The transformation into XStandoff requires an input XML file ideally containing elements bound by XML namespaces.

                Every single namespace evokes the output of a layer in XStandoff which contains the elements from the namespace.

                Thereby the default (or empty) namespace is treated like the named ones. Thus inline annotations without explicit namespace 

                declarations can also be processed (in this case a namespace will be generated).
</p>

            
<p>The process of converting an inline annotation to XStandoff is divided into two steps: Firstly, segments are built on the basis of 

                the occurring elements. There are two possible ways of mapping the element boundaries to the textual content in the form of 

                character positions. The preferred way of reaching such a mapping is the use of a primary data file which contains the bare text 

                without annotations. The name of this file can be provided during the transformation call by specifying the stylesheet parameter 

                primary-data. Providing the location of a primary data file leads to a comparison of the content of the primary data file and the 

                textual content of the input file of the transformation. This guarantees primary data identity. If no primary data location is provided, 

                the textual content of the input file is used to build up the primary data. This has certain disadvantages such as the lack of line 

                breaks since these cannot easily be inferred by the textual content of an XML file. Furthermore, the automatic conversion of the 

                textual content of the input file to be used as primary data relies on heuristics which have to guess white spaces. Because of the 

                complexity of this task it is possible to get undesirable results.
</p>

            
<p>After the building of segments, the second step of the transformation is to return layers on the basis of namespaces. Thus for 

                every namespace the corresponding elements are released from the initial inline annotation and copied into the layer maintaining 

                the embedding relations. Meanwhile the elements in the XStandoff layer get connected to the according segments by ID/IDREF 

                binding. In this manner one segment can serve as a reference for elements from different layers.
</p>

            
<p><b>Input XML file:</b> file containing inline annotation containing namespaces (used to generate layers) </p>

            
<p><b>Additional file (required):</b> a second XSF instance which should be merged with the first one</p>

            
<p><b>Stylesheet parameters:</b> see individual documentation</p>

            
<p><b>Execution via command line (XSLT processor Saxon9):</b> java -jar saxon9.jar [optional Saxon Parameters] -o [XML output filename] [XML input filename] inline2XSF.xsl [optional Stylesheet Parameters, see below]</p>

        
</xd:detail>

    
</xd:doc>


    

        

    
<xsl:output method="xml" indent="yes" />

    

    
<!-- ##### Stylesheet Parameters ##### -->

    
         <xd:doc type="xs:string"><xd:short><p>Name of a txt-file containing the primary data. If omitted then primary data is generated from the text data of XML input</p></xd:short></xd:doc>


    
<xsl:param name="primary-data" as="xs:string?" required="no" /><!--in fact required - tested manually-->

    

    
         <xd:doc type="XPath expression"><xd:short><p>XPath expression identifying element which serves as root of the actual annotation (default: document node) to be included in layers -&gt; saxon call sample: virtual-root=//*:text</p></xd:short></xd:doc>


    
<xsl:param name="virtual-root" select="'/'" as="xs:string" required="no" />

    

    
         <xd:doc type="xs:boolean"><xd:short><p>If true then local XSDs are used, false - XSDs from http://www.xstandoff.net/2009/xstandoff/1.1... are used</p></xd:short></xd:doc>


    
<xsl:param name="local-xsd" select="false()" as="xs:boolean" required="no" />

    

    
         <xd:doc type="xs:boolean"><xd:short><p>Determines whether or not primary data should be copied to element xsf:primaryData</p></xd:short></xd:doc>


    
<xsl:param name="copy-primary-data-to-xsf" select="false()" as="xs:boolean" required="no" />

    

    
         <xd:doc type="XPath expression"><xd:short><p>Determines the location of meta data which is to be copied to element xsf:meta ( in saxon call give XPath for respective element: meta-root="//*:meta )</p></xd:short></xd:doc>


    
<xsl:param name="meta-root" select="'()'" as="xs:string" required="no" />

    

    
         <xd:doc type="xs:boolean"><xd:short><p>Value true includes optional elements into the result of the transformation</p></xd:short></xd:doc>


    
<xsl:param name="include-optional-elements" select="false()" as="xs:boolean" required="no" />

    

    
         <xd:doc type="xs:boolean"><xd:short><p>Determines which empty element should get @xsf:segment; '#all' means that all empty elements get a segment reference; e.g. 'chs,cnx' means only elements with prefixes chs und cnx get segment reference</p></xd:short></xd:doc>


    
<xsl:param name="levels-empty-elements" select="'#all'" as="xs:string" required="no" />

    

    
         <xd:doc type="xs:boolean"><xd:short><p>True includes segments for whitespaces into the result of the transformation</p></xd:short></xd:doc>


    
<xsl:param name="include-ws-segments" select="false()" as="xs:boolean" required="no" />

    

    
         <xd:doc type="xs:string"><xd:short><p>True ('1') has effect that all nodes from the XML input are included in a single xsf-layer</p></xd:short></xd:doc>


    
<xsl:param name="file-in-one-layer" select="false()" as="xs:boolean" required="no" />

    

    
         <xd:doc type="xs:string"><xd:short><p>Whether or not elements which occur in all layers shall be returned in a separate layer</p></xd:short></xd:doc>


    
<xsl:param name="all-layer" select="false()" as="xs:boolean" required="no" />

    

    
         <xd:doc type="xs:string"><xd:short><p>Version of returned XSF</p></xd:short></xd:doc>


    
<xsl:param name="xsfVersion" select="'1.1'" as="xs:string" required="no" />

    

    
         <xd:doc type="xs:string">

        
<xd:short>

            
<p>Strength of primary data check: lax, middle (default) or strict.</p>

            
<ul>

                
<li>

                    lax: Minimum of primary data identity, i.e. non-whitespace characters must be identical in XML annotation's text content and primary data file.

                    Only whitespaces from primary data which must be present in XML are those in XML annotation's terminal text nodes.

                
</li>

                
<li>middle: Like 'lax', but all characters, also whitespaces, from primary data file must be present in XML annotation's text nodes.</li>

                
<li>strict: Like 'middle', but indents and additional whitespaces are only allowed within mixedConent and at the boundaries of terminal text nodes.</li>

            
</ul>

        
</xd:short>

    
</xd:doc>


    
<xsl:param name="pd-check" select="'middle'" as="xs:string" required="no" />

    

    
         <xd:doc type="xs:boolean"><xd:short><p>If set to true() then all pure whitespace text nodes are removed from input XML and positions are inferred completely heuristically.</p></xd:short></xd:doc>


    
<xsl:param name="heuristic-ws-search" select="false()" as="xs:boolean" />

    

    
         <xd:doc type="xs:string"><xd:short><p>En-/Disable extended messaging</p></xd:short></xd:doc>


    
<xsl:param name="ANALYZE-BUGS" select="false()" as="xs:boolean" required="no" />

    

    
         <xd:doc type="xs:integer"><xd:short><p>Level of returned messages for bug analysis</p></xd:short></xd:doc>


    
<xsl:param name="bug-message-level" select="0" as="xs:integer" required="no" />

    
<!-- ########################### -->

    

    

    
<!-- ########## Keys ############ -->

    
         <xd:doc><xd:short><p>Find elements by their ID attribute; no matter which namespace @id is bound by</p></xd:short></xd:doc>


    
<xsl:key name="elem-by-id" match="element()" use="@*:id" />

    

    
         <xd:doc><xd:short><p>Find elements by their specific namespace URIs they are connected to</p></xd:short></xd:doc>


    
<xsl:key name="elem-by-namespace-uri" match="element()" use="namespace-uri(.)" />

    

    
         <xd:doc><xd:short><p>Find elements by position information provided by descending xsf:c/@p</p></xd:short></xd:doc>


    
<xsl:key name="element-by-positions" match="element()" use="concat(descendant::xsf:c[1]/@p, '-', descendant::xsf:c[last()]/@p)" />

    

    
         <xd:doc><xd:short><p>Find XSF segments by their start and end positions</p></xd:short></xd:doc>


    
<xsl:key name="segment-by-positions" match="xsf:segment" use="concat(@start, '-', @end)" />

    

    
<!-- ########################### -->

    

    

    
<!-- ##### Global Variables ##### -->

    
         <xd:doc type="xs:string"><xd:short>Referencing the original root node of the input document</xd:short></xd:doc>


    
<xsl:variable name="root" select="/" />

    

    
         <xd:doc type="xs:string"><xd:short><p>Making $primary-data usable as URI for document()</p></xd:short></xd:doc>


    
<xsl:variable name="primary-data-file" select="replace($primary-data, '\\', '/')" as="xs:string" />

    

    
         <xd:doc type="xs:string"><xd:short><p>Saving primary data (either from file provided by stylesheet parameter or from textual data of XML input)</p></xd:short></xd:doc>


    
<xsl:variable name="primary-data-string" select="replace(unparsed-text($primary-data-file, 'UTF-8'), ' ', '')" as="xs:string" />

    

    
         <xd:doc type="xs:string"><xd:short><p>Name of the input xml file, e.g. used for @xml:id in element xsf:corpusData</p></xd:short></xd:doc>


    
<xsl:variable name="baseFileName" select="substring-before(tokenize(document-uri(/), '/')[last()], '.xml')" as="xs:string" />

    

    
         <xd:doc type="xs:string"><xd:short><p>Defines the directory of the schema location with respect to the stylesheet parameter $local-xsd</p></xd:short></xd:doc>


    
<xsl:variable name="xsd-location" select="if($local-xsd) then '' else 'http://www.xstandoff.net/2009/xstandoff/1.1/'" as="xs:string" />

    

    
         <xd:doc type="xs:anyURI+"><xd:short><p>Namespaces which can be found in input XML file</p></xd:short></xd:doc>


    
<xsl:variable name="distinct-namespaces" select="distinct-values($virtual-root-node//*/namespace-uri(.))" as="xs:anyURI+" />

    

    
         <xd:doc type="xs:boolean"><xd:short><p>There are conditions under which an all-layer should not be returned</p></xd:short></xd:doc>


    
<xsl:variable name="include-all-layer" select="$all-layer and exists($distinct-namespaces[2])" as="xs:boolean" />

    

    
         <xd:doc type="xs:string"><xd:short><p>This assignable variable contains the textual content of the element determined by stylesheet parameter virtual-root (with whitespaces)</p></xd:short></xd:doc>


    
<xsl:variable name="text-data-string" select="string-join($virtual-root-node//text(), '')" as="xs:string" saxon:assignable="yes" />

    

    
         <xd:doc type="xs:string?"><xd:short><p>Primary data without whitespaces</p></xd:short></xd:doc>
 

    
<xsl:variable name="primaryData_noWS" select="replace($primary-data-string, '\s', '')" as="xs:string?" />

    

    
         <xd:doc type="xs:string"><xd:short><p>This variable contains the textual content of the element determined by stylesheet parameter virtual-root (without whitespaces)</p></xd:short></xd:doc>


    
<xsl:variable name="textData_noWS" select="replace(string-join($virtual-root-node//text(), ''), '\s', '')" as="xs:string?" />

    

    
         <xd:doc type="xs:string"><xd:short><p>This assignable variable contains the textual content of the element determined by stylesheet parameter virtual-root (without whitespaces)</p></xd:short></xd:doc>


    
<xsl:variable name="text-data-repl-mC-ws" select="''" as="xs:string" saxon:assignable="yes" />

    

    
         <xd:doc type="xs:string"><xd:short><p>Directory for result-documents for bug analysis</p></xd:short></xd:doc>


    
<xsl:variable name="log-directory" select="'logs/'" as="xs:string" />

    

    
         <xd:doc><xd:short><p>Variable containing the element which is provided by stylesheet parameter virtual-root</p></xd:short></xd:doc>


    
<xsl:variable name="virtual-root-node">

        
<xsl:for-each select="saxon:eval(saxon:expression($virtual-root))">

            
<xsl:document><xsl:copy-of select="." /></xsl:document>

        
</xsl:for-each>

    
</xsl:variable>

    

    
         <xd:doc><xd:short><p>Variable containing the element which is provided by stylesheet parameter meta-root</p></xd:short></xd:doc>


    
<xsl:variable name="meta-root-node">

        
<xsl:if test="$meta-root!='()'">

            
<xsl:document><xsl:copy-of select="saxon:eval(saxon:expression( $meta-root ))" /></xsl:document>

        
</xsl:if>

    
</xsl:variable>

    

    
         <xd:doc><xd:short><p>This assignable variable allows replacing of textual content (which is in mixed content section) from $replaced-non-mC-text with position information</p></xd:short></xd:doc>


    
<xsl:variable name="segmentation-base" saxon:assignable="yes" />

    

    
         <xd:doc><xd:short><p>This assignable variable contains the segments for the input XML, built on the basis of the replaced text XML ($segmentation-base)</p></xd:short></xd:doc>


    
<xsl:variable name="segmentation" saxon:assignable="yes" />

    

    
         <xd:doc type="xs:integer"><xd:short><p>Saxon assignable variable for iteration</p></xd:short></xd:doc>


    
<xsl:variable name="iter" select="1" as="xs:integer" saxon:assignable="yes" />

    

    
         <xd:doc type="xs:string*"><xd:short><p>Saxon assignable variable for storing textual content of segments and later replacement by position information</p></xd:short></xd:doc>


    
<xsl:variable name="pd-replaced-positions" select="()" as="xs:string*" saxon:assignable="yes" />

    

    
         <xd:doc type="xs:string"><xd:short><p>Saxon assignable variable for storing textual content of text nodes in mixed content sections which precede the non-mC-text-node in question, but do 

    not precede the first preceding non-mC text node
</p></xd:short></xd:doc>


    
<xsl:variable name="prec-non-mC-text-node-preceding-mC-text-nodes" select="''" as="xs:string" saxon:assignable="yes" />

    

    
         <xd:doc type="xs:string*"><xd:short><p>Supportive variable for processing empty elements in replace-non-mC-text</p></xd:short></xd:doc>


    
<xsl:variable name="first-non-mC-text-node-processed" select="false()" as="xs:boolean" saxon:assignable="yes" />

    

    
         <xd:doc type="element()+"><xd:short><p>Determination of different layers with respect to namespaces in XML input file ($distinct-namespaces)</p></xd:short></xd:doc>


    
<xsl:variable name="layers" as="element()+">

        
<xsl:message select="' $ Instantiating variable $layers'" />

        
<xsl:for-each select="if($file-in-one-layer) then /element()[1]/namespace-uri() else ( xs:anyURI('http://www.xstandoff.net/2009/all')[$include-all-layer], $distinct-namespaces )">

            
<xsf:layer>

                
<xsl:copy-of select="attr:return-atts-for-elems-from-namespace(if($file-in-one-layer) then $distinct-namespaces else .)" />

            
</xsf:layer>

        
</xsl:for-each>

    
</xsl:variable>

    

    
         <xd:doc type="element()+"><xd:short><p>Variable containing information about different layers (especially element names)</p></xd:short></xd:doc>


    
<xsl:variable name="layerSEG" as="element()+">

        
<xsl:message select="' $ Instantiating variable $layerSEG'" />

        
<xsl:for-each select="$layers">

            
<xsl:variable name="thisLayersPrefix" select="prefix-from-QName( node-name(@*[1]) )" as="xs:string?" />

            
<xsl:variable name="thisLayersURI" select="namespace-uri-from-QName( node-name(@*[1]) )" as="xs:anyURI?" />

            
<xsl:message select="' # Processing layer: ', $thisLayersPrefix, '/', $thisLayersURI" />

            
<!--when current layer is all-layer, then there should be some content for it-->

            
<xsl:if test="if($thisLayersPrefix='all') then exists(@* except @all:all) else true()">

                
<layer>

                    
<xsl:for-each select="$virtual-root-node">

                        
<xsl:choose>

                            
<xsl:when test="$file-in-one-layer">

                                
<xsl:copy-of select="." />

                            
</xsl:when>

                            
<xsl:otherwise>

                                
<xsl:choose>

                                    
<!--if currently processed layer is the all-layer, then the segments from $segments4elements-in-all-layer have to be inlined-->

                                    
<xsl:when test="$thisLayersPrefix='all'">

                                        
<xsl:copy-of select="undef:segments2inline($segments4elements-in-all-layer/*)" />

                                    
</xsl:when>

                                    
<!--if currently processed layer is not the all-layer, then it can be copied on the basis of the current context $layers-->

                                    
<xsl:otherwise>

                                        
<xsl:call-template name="copy-nodes-by-namespace-uri" exclude-result-prefixes="#all">

                                            
<xsl:with-param name="uri" select="$thisLayersURI" as="xs:anyURI?" />

                                        
</xsl:call-template>

                                    
</xsl:otherwise>

                                
</xsl:choose>

                            
</xsl:otherwise>

                        
</xsl:choose>

                    
</xsl:for-each>

                
</layer>

            
</xsl:if>

        
</xsl:for-each>

    
</xsl:variable>

    

    
         <xd:doc><xd:short><p>Finding segments which reference elements occuring in all namespaces</p></xd:short></xd:doc>


    
<xsl:variable name="segments4elements-in-all-layer">

        
<xsl:message select="' $ Instantiating variable $segments4elements-in-all-layer'" />

        
<xsl:if test="$all-layer and exists($layers[2])">

            
<xsl:for-each select="$segmentation//xsf:segment">

                
<xsl:variable name="atts" select="@xml:id, @start, @end" />

                
<xsl:variable name="elements-this-segment" select="key('element-by-positions', concat(@start, '-', @end), $segmentation-base)" as="element()+" />

                
<xsl:for-each select="for $local-name in distinct-values($elements-this-segment/local-name()) return $local-name[every $ns in $distinct-namespaces satisfies exists($elements-this-segment[local-name()=$local-name and namespace-uri(.)=$ns])]">

                    
<xsf:segment xml:id="{$atts[1]}" local-name="{.}" generated-IDs="{$elements-this-segment[local-name()=current()]/generate-id()}" start="{$atts[2]}" end="{$atts[3]}">

                        
<xsl:for-each select="$elements-this-segment/@*">

                            
<xsl:attribute name="{string(node-name(.))}" select="." namespace="{namespace-uri(.)}" />

                        
</xsl:for-each>

                    
</xsf:segment>

                
</xsl:for-each>

            
</xsl:for-each>

        
</xsl:if>

    
</xsl:variable>

    

    
<xsl:variable name="removed-ws-text-nodes">

        
<xsl:for-each select="$virtual-root-node">

            
<xsl:apply-templates mode="remove-ws-text-nodes" />

        
</xsl:for-each>

    
</xsl:variable>

    
<!--#########################-->

    

    

    
<!-- ######## Templates ######## -->

    
         <xd:doc>

        
<xd:short><p>Template matching the root of the document to be transformed.</p></xd:short>

        
<xd:detail>

            
<p>

                The initial template is naturally the starting point of the transformation. In this special case, several tasks are involved:

                
<ul>

                    
<li>Returning messages on supplied stylesheet parameters → <i>undef:param-messages()</i></li>

                    
<li>Checking for primary data identity → <i>undef:check-primary-data()</i></li>

                    
<li>Replacing non-mixed-content characters by position information (template mode: <i>replace-non-mC-text</i>)</li>

                    
<li>Replacing mixed-content characters by position information (template mode: <i>replace-mC-text</i>)</li>

                    
<li>Deriving a segmentation on the basis of position information</li>

                    
<li>Returning the XSF annotation by processing individual layers</li>

                
</ul>

                Detailed information on the several processing steps is available at the documentation of the individual templates and functions called.

            
</p>

        
</xd:detail>

    
</xd:doc>


    
<xsl:template match="/">

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### START: match=''/'' ###')" />

        

        
<!--Testing parameter primary-data -->

        
<xsl:choose>

            
<!--ERROR if it is not set properly-->

            
<xsl:when test="empty($primary-data) or $primary-data = ''">

                
<xsl:message select="'*** ERROR: No value supplied for parameter primary-data'" />

                
<xsl:message select="'*** ATTENTION: Please give the location of a primary data file or provide the string ''create'' as value to create a primary data file.'" terminate="yes" />

            
</xsl:when>

            
<!--if it is set to create primary-data automatically-->

            
<xsl:when test="lower-case($primary-data) = ('create', '''create''')">

                
<xsl:result-document href="{concat($baseFileName, '-pd.txt')}" method="text">

                    
<xsl:for-each select="$virtual-root-node">

                        
<!--textual data from XML being inferred-->

                        
<xsl:call-template name="build-primary-data-from-XML">

                            
<xsl:with-param name="XMLdata" as="node()+">

                                
<!--XML data getting normalized-->

                                
<xsl:call-template name="normalize" />

                            
</xsl:with-param>

                        
</xsl:call-template>

                    
</xsl:for-each>

                
</xsl:result-document>

                
<xsl:message select="concat('*** ATTENTION: Created primary data file ''', $baseFileName, '-pd.txt'' automatically. Please check correctness and use for inline2XSF transformation.')" terminate="yes" />

            
</xsl:when>

        
</xsl:choose>

        

        

        
<!--changing context to $virtual-root-node-->

        
<xsl:for-each select="$virtual-root-node">

            

            
<!--returning information on stylesheet parameters-->

            
<xsl:copy-of select="undef:param-messages()" />

            

            
<!--checking primary data identity of XML text and primary data text / checking correctness of $pd-check and $virtual-root-node-->

            
<xsl:copy-of select="undef:check-primary-data()" />

            

            
<!--#########################################################

                ########## to be sure to have the right serialization order ############

                #########  assignable global variables are assigned here  ###########

                ##########################################################
-->

            

            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 1, 'SAXON-ASSIGN :: $segmentation-base (positions of non-mixed content)')" />

            
<saxon:assign name="segmentation-base">

                
<xsl:for-each select="if($heuristic-ws-search) then $removed-ws-text-nodes else .">

                    
<xsl:document>

                        
<xsl:apply-templates mode="replace-non-mC-text" />

                    
</xsl:document>

                
</xsl:for-each>

            
</saxon:assign>

            

            

            
<!--for analyzing bugs-->

            
<xsl:if test="$ANALYZE-BUGS and $bug-message-level &gt;= 2">

                
<xsl:result-document href="{concat($log-directory, 'pd-replaced-positions.txt')}" method="text">

                    
<xsl:copy-of select="concat('(', string-join(for $item in $pd-replaced-positions return concat('''', $item, ''''), ', '), ')')" />

                
</xsl:result-document>

                

                
<xsl:result-document href="{concat($log-directory, 'replaced-non-mC-text.xml')}">

                    
<xsl:copy-of select="$segmentation-base" />

                
</xsl:result-document>

            
</xsl:if>

            

            

            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 1, 'SAXON-ASSIGN :: $segmentation-base (positions of mixed content)')" />

            
<saxon:assign name="segmentation-base">

                
<xsl:document>

                    
<saxon:assign name="pd-replaced-positions" select="$pd-replaced-positions, substring($primary-data-string, $iter + 1)" />

                    
<xsl:for-each select="$segmentation-base">

                        
<!--iter is now used to signal the current position in $pd-replaced-positions-->

                        
<saxon:assign name="iter" select="1" />

                        
<xsl:apply-templates mode="replace-mC-text" />

                    
</xsl:for-each>

                
</xsl:document>

            
</saxon:assign>

            

            

            
<xsl:if test="$ANALYZE-BUGS and $bug-message-level &gt;= 2">

                
<xsl:result-document href="{concat($log-directory, 'replaced-mC-text.xml')}">

                    
<xsl:copy-of select="$segmentation-base" />

                
</xsl:result-document>

            
</xsl:if>

            

            

            

            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 1, 'SAXON-ASSIGN :: $segmentation-base (positions of empty elements)')" />

            
<saxon:assign name="segmentation-base">

                
<xsl:document>

                    
<xsl:for-each select="$segmentation-base">

                        
<xsl:apply-templates mode="replace-empty-elements" />

                    
</xsl:for-each>

                
</xsl:document>

            
</saxon:assign>

            

            

            
<xsl:if test="$ANALYZE-BUGS and $bug-message-level &gt;= 2">

                
<xsl:result-document href="{concat($log-directory, 'replaced-empty-elements.xml')}">

                    
<xsl:copy-of select="$segmentation-base" />

                
</xsl:result-document>

            
</xsl:if>

            

            

            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 1, 'SAXON-ASSIGN :: $segmentation')" />

            
<saxon:assign name="segmentation">

                
<xsl:document>

                    
<xsf:segmentation>

                        
<xsl:for-each select="distinct-values($segmentation-base//*/concat(descendant::xsf:c[1]/@p, '-', descendant::xsf:c[last()]/@p))[. != '-']">

                            
<xsf:segment xml:id="{concat('seg', position())}" start="{tokenize(., '-')[1]}" end="{tokenize(., '-')[2]}" />

                        
</xsl:for-each>

                    
</xsf:segmentation>

                
</xsl:document>

            
</saxon:assign>

            

            
<!--#################### end of assigning ########################

                ###########################################################
-->

             

            
<xsf:corpusData xsi:schemaLocation="{concat('http://www.xstandoff.net/2009/xstandoff/1.1', ' ', $xsd-location, 'xsf.xsd')}" xsfVersion="{$xsfVersion}" xml:id="{string:ID-comform($baseFileName)}">

                

                
<!-- ########for analyzing bugs only########## -->

                
<xsl:if test="$ANALYZE-BUGS and $bug-message-level &gt;= 2">

                    
<xsl:result-document href="{concat($log-directory, 'layers.xml')}" indent="no">

                        
<xsf:layers><xsl:copy-of select="$layers" /></xsf:layers>

                    
</xsl:result-document>

                    
<xsl:result-document href="{concat($log-directory, 'layerSEG.xml')}" indent="no">

                        
<xsf:layerSEG><xsl:copy-of select="$layerSEG" /></xsf:layerSEG>

                    
</xsl:result-document>

                    
<xsl:result-document href="{concat($log-directory, 'all-layer-segs.xml')}" indent="no">

                        
<xsf:seg><xsl:copy-of select="$segments4elements-in-all-layer" /></xsf:seg>

                    
</xsl:result-document>

                    
<xsl:result-document href="{concat($log-directory, 'segmentation-base.xml')}" indent="no">

                        
<xsf:rep><xsl:copy-of select="$segmentation-base" /></xsf:rep>

                    
</xsl:result-document>

                
</xsl:if>

                

                
<xsl:if test="$include-optional-elements">

                    
<xsf:meta>

                        
<olac:olac xmlns:dcterms="http://purl.org/dc/terms/" xmlns:olac="http://www.language-archives.org/OLAC/1.0/" xmlns="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.language-archives.org/OLAC/1.0/ meta/olac.xsd">

                            
<creator />

                            
<date />

                            
<description />

                        
</olac:olac>

                    
</xsf:meta>

                
</xsl:if>

                

                
<xsl:if test="$meta-root != '()'">

                    
<xsf:meta>

                        
<xsl:copy-of select="$meta-root-node" exclude-result-prefixes="#all" />

                    
</xsf:meta>

                
</xsl:if>

                

                
<xsf:primaryData start="0" end="{string-length($primary-data-string)}">

                    
<xsl:if test="exists($virtual-root-node//(@xml:lang|@lang))">

                        
<xsl:attribute name="xml:lang" select="($virtual-root-node//@*:lang)[1]" />

                    
</xsl:if>

                    
<xsl:choose>

                        
<xsl:when test="$primary-data='' or $copy-primary-data-to-xsf">

                            
<xsf:textualContent><xsl:copy-of select="$primary-data-string" /></xsf:textualContent>

                        
</xsl:when>

                        
<xsl:when test="$primary-data!=''">

                            
<xsl:element name="{if($xsfVersion='1.0') then 'location' else if($xsfVersion='1.1') then 'xsf:primaryDataRef' else error((), '$xsfVersion has invalid value')}">

                                
<xsl:attribute name="uri" select="$primary-data" />

                            
</xsl:element>

                        
</xsl:when>

                        
<xsl:otherwise>

                            
<xsl:message select="'*** ERROR: neither element primaryDataRef nor textualContent could be specified!'" terminate="yes" />

                        
</xsl:otherwise>

                    
</xsl:choose>

                    
<xsl:if test="$include-optional-elements">

                        
<xsf:checksum algorithm="md5" />

                    
</xsl:if>

                
</xsf:primaryData>

                
<xsl:copy-of select="$segmentation" />

                

                
<!--processing individual layers-->

                
<xsf:annotation>

                    
<xsl:for-each select="$layers [ exists(@all:all) or ( if($all-layer) then ( (:###making namespace of layer available###:) for $this-namespace in namespace-uri-from-QName(node-name(@*[1])) return (:###actual condition###:) some $elem in $segmentation-base//*[namespace-uri() = $this-namespace] satisfies empty( index-of(for $genIDs in $segments4elements-in-all-layer//@generated-IDs return tokenize($genIDs, ' '), $elem/generate-id()) ) ) else true() ) ]">     

                        
<xsl:variable name="thisLayersURI" select="namespace-uri-from-QName(node-name(@*[1]))" as="xs:anyURI?" />

                        
<xsl:variable name="thisLayersPrefix" select="if($thisLayersURI='http://www.xstandoff.net/2009/all') then 'all' else prefix-from-QName(node-name( (key('elem-by-namespace-uri', $thisLayersURI, $virtual-root-node))[1] ))" as="xs:string?" />

                        
<!--when currently processed layer is all-layer, then there should be some content for it, otherwise not returned-->

                        
<xsl:if test="if($thisLayersPrefix='all') then exists(@* except @all:all) else true()">

                            
<xsf:level xml:id="{concat(string:ID-comform($baseFileName), '-level', position())}">

                                
<xsl:if test="$xsfVersion='1.0'">

                                    
<xsl:attribute name="priority" select="0" />

                                
</xsl:if>

                                
<xsl:if test="$include-optional-elements">

                                    
<xsf:meta>

                                        
<olac:olac xmlns:dcterms="http://purl.org/dc/terms/" xmlns:olac="http://www.language-archives.org/OLAC/1.0/" xmlns="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.language-archives.org/OLAC/1.0/ meta/olac.xsd">

                                            
<format />

                                            
<dcterms:isFormatOf />

                                            
<creator />

                                            
<date />

                                            
<description />

                                        
</olac:olac>

                                    
</xsf:meta>

                                
</xsl:if>

                                
<xsf:layer>

                                    
<xsl:if test="$xsfVersion='1.1'">

                                        
<xsl:attribute name="priority" select="0" />

                                    
</xsl:if>

                                    
<xsl:if test="$thisLayersURI != ''">

                                        
<xsl:if test="not($file-in-one-layer)">

                                            
<xsl:namespace name="{$thisLayersPrefix}" select="$thisLayersURI" />

                                        
</xsl:if>

                                        
<!-- There are several possible solutions of identifying the schemaLocation for an individual layer -->

                                        
<xsl:variable name="schemaLocation" select="( ($virtual-root-node/descendant::element()[namespace-uri() = $thisLayersURI])[1]/@xsi:schemaLocation, $virtual-root-node/element()[1]/@xsi:schemaLocation, ($root//element()[namespace-uri() = $thisLayersURI])[1]/@xsi:schemaLocation, if($thisLayersPrefix!='all' and $thisLayersPrefix!='') then concat($thisLayersURI, ' ', $thisLayersPrefix, '.xsd') else '' )[1]" as="xs:string" />

                                        
<xsl:if test="$schemaLocation">

                                            
<xsl:attribute name="xsi:schemaLocation" select="$schemaLocation" />

                                        
</xsl:if>

                                    
</xsl:if>

                                    
<xsl:choose>

                                        
<!--segments from all-layer ($segments4elements-in-all-layer) have to be inlined-->

                                        
<xsl:when test="$thisLayersURI='http://www.xstandoff.net/2009/all'">

                                            
<xsl:copy-of select="undef:segments2inline($segments4elements-in-all-layer/*)" />

                                        
</xsl:when>

                                        
<!--recursive copy of nodes from particular namespace-->

                                        
<xsl:otherwise>

                                            
<xsl:for-each select="$segmentation-base">

                                                
<xsl:apply-templates mode="copy-segmentation-base">

                                                    
<xsl:with-param name="namespace-uri" select="if($file-in-one-layer) then 'all' else $thisLayersURI" />

                                                
</xsl:apply-templates>

                                            
</xsl:for-each>

                                        
</xsl:otherwise>

                                    
</xsl:choose>

                                
</xsf:layer>

                            
</xsf:level>

                        
</xsl:if>

                    
</xsl:for-each>

                
</xsf:annotation>

                
<xsl:if test="$include-optional-elements">

                    
<xsf:log />

                
</xsl:if>

            
</xsf:corpusData>

        
</xsl:for-each>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### END: match=''/'' ###')" />

    
</xsl:template>

    

    

    
<xsl:template match="text()" />

    

    

    
         <xd:doc>

        
<xd:short><p>Template for replacing non-mixed-content characters of the input annotation by corresponding position information.</p></xd:short>

        
<xd:detail>

            
<p>A pointer (incrementing $iter) leads through the textual content (in this case only non-mixed-content) of the input annotation and outputs position information where applicable.</p>

            
<p>The information is returned by replacing the textual content by elements like the following: 

                &lt;xsf:c p="{current character position}"&gt;
</p>

        
</xd:detail>

    
</xd:doc>


    
<xsl:template match="document-node() | element() | text() | attribute() | processing-instruction() | comment()" mode="replace-non-mC-text">

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### START: mode=''replace-non-mC-text'' ###')" />

        
<xsl:choose>

            
<xsl:when test="self::element()">

                
<xsl:copy>

                    
<xsl:copy-of select="@*" />

                    
<xsl:choose>

                        
<xsl:when test="empty(text()|element())">

                            
<!--processing of empty elements at last-->

                            
<!--<xsf:c p="{if($first-non-mC-text-node-processed) then $iter else ($iter - 1)}"/>-->

                        
</xsl:when>

                        
<xsl:otherwise>

                            
<xsl:apply-templates mode="replace-non-mC-text" />

                        
</xsl:otherwise>

                    
</xsl:choose>

                
</xsl:copy>

            
</xsl:when>

            
<xsl:when test="self::text()">

                
<xsl:choose>

                    
<!--if text node is in mixed content section-->

                    
<xsl:when test="bool:self-in-mC(.)">

                        
<!--concatenation of text nodes between non-mixed content text nodes-->

                        
<saxon:assign name="prec-non-mC-text-node-preceding-mC-text-nodes" select="concat($prec-non-mC-text-node-preceding-mC-text-nodes, .)" />

                        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-non-mC-text'' :: bool:self-in-mC(''', ., ''') = true'))" />

                        
<xsl:copy-of select="." />

                    
</xsl:when>

                    
<!--if text node is not in mixed content-->

                    
<xsl:otherwise>

                        

                         
<xsl:variable name="prec-text-node-string" select="replace( $prec-non-mC-text-node-preceding-mC-text-nodes, '\s', '' )" as="xs:string?" />

                        
<xsl:if test="$prec-text-node-string != ''">

                            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, concat('$prec-text-node-string=''', $prec-text-node-string, ''''))" />

                            
<xsl:variable name="iterate-non-ws" select="undef:iterate-non-ws(substring($primary-data-string, $iter + 1), $prec-text-node-string, 0)" as="xs:integer" />

                            
<xsl:choose>

                                
<xsl:when test="$iterate-non-ws != 0">

                                    
<!--1st try was successful-->

                                    
<saxon:assign name="iter" select="$iter + $iterate-non-ws" />

                                
</xsl:when>

                                
<xsl:otherwise>

                                    
<xsl:variable name="iterate-non-ws" select="undef:iterate-non-ws(substring($primary-data-string, $iter), $prec-text-node-string, 0)" as="xs:integer" />

                                    
<xsl:choose>

                                        
<xsl:when test="$iterate-non-ws != 0">

                                            
<!--2nd try was successful-->

                                            
<saxon:assign name="iter" select="$iter + $iterate-non-ws" />

                                        
</xsl:when>

                                        
<xsl:otherwise>

                                            
<!-- ERROR :: substring does not start with 1st char of $prec-text-node-string -->

                                            
<xsl:message select="'*** ERROR: undef:iterate-non-ws() :: no result'" />

                                            
<xsl:message select="concat('*** substring($primary-data-string, $iter + 1)=''', substring($primary-data-string, $iter + 1), '''')" />

                                            
<xsl:message select="concat('*** substring($primary-data-string, $iter)=''', substring($primary-data-string, $iter), '''')" />

                                            
<xsl:message select="concat('*** $iter=''', $iter, '''')" />

                                            
<xsl:message select="concat('*** $prec-text-node-string=''', $prec-text-node-string, '''')" terminate="yes" />

                                        
</xsl:otherwise>

                                    
</xsl:choose>

                                
</xsl:otherwise>

                            
</xsl:choose>

                            

                        
</xsl:if>

                        
<saxon:assign name="prec-non-mC-text-node-preceding-mC-text-nodes" select="''" />

                        

                        
<saxon:assign name="first-non-mC-text-node-processed" select="true()" />

                        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-non-mC-text'' :: bool:self-in-mC(''', ., ''') = false'))" />

                        
<xsl:variable name="start-end" select="for $pos in int:substring-positions( substring($primary-data-string, $iter) , (:##. is self::text()##:) . ) return ($pos + $iter) - 1" as="xs:integer*" />

                        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, 'MODE ''replace-non-mC-text'' :: ________________')" />

                        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-non-mC-text'' :: self::text() = ''', ., ''''))" />

                        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, concat('MODE ''replace-non-mC-text'' :: substring($primary-data-string, ', $iter, '): ''', substring($primary-data-string, $iter), ''''))" />

                        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-non-mC-text'' :: $pos:', string:int2string(int:substring-positions(substring($primary-data-string, $iter), (:##self::text()##:) . ))))" />

                        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-non-mC-text'' :: $start-end:', string:int2string($start-end)))" />

                        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, 'MODE ''replace-non-mC-text'' :: ________________')" />

                        
<xsl:for-each select="$start-end">

                            
<xsf:c p="{.}" />

                        
</xsl:for-each>

                        
<saxon:assign name="iter" select="$start-end[2]" />

                        
<xsl:variable name="end-preceding-seg" select="xs:integer(( substring-before(substring-after($pd-replaced-positions[last()], '['), ']')[.!=''], 0)[1])" as="xs:integer" />

                        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, string-join(('MODE ''replace-non-mC-text'' :: insert ''', substring($primary-data-string, ($end-preceding-seg + 1), ($start-end[1] - $end-preceding-seg))[.!=''], ''' into pd-replaced-positions'), ''))" />

                        
<saxon:assign name="pd-replaced-positions" select="$pd-replaced-positions, (:###item for preceding mC-text###:) substring($primary-data-string, ($end-preceding-seg + 1), ($start-end[1] - $end-preceding-seg))[.!=''], (:###two items for current non-mC-txt###:) concat('[', $start-end[1], ']'), concat('[', $start-end[2], ']')" />

                    
</xsl:otherwise>

                
</xsl:choose>

            
</xsl:when>

            
<xsl:when test="self::comment() | self::processing-instruction()">

                
<xsl:copy-of select="." />

            
</xsl:when>

        
</xsl:choose>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### END: mode=''replace-non-mC-text'' ###')" />

    
</xsl:template>

    

    

    
         <xd:doc>

        
<xd:short><p>Template for replacing mixed-content characters of the input annotation by corresponding position information.</p></xd:short>

        
<xd:detail>

            
<p>A pointer leads through the textual content (in this case only mixed-content) of the input annotation and outputs position information where applicable.</p>

            
<p>The information is returned by replacing the textual content by elements like the following: 

                &lt;xsf:c p="{current character position}"&gt;
</p>

        
</xd:detail>

    
</xd:doc>


    
<xsl:template match="element() | text() | attribute() | processing-instruction() | comment()" mode="replace-mC-text">

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### START: mode=''replace-mC-text'' ###')" />

        
<!--iterating $pd-replaced-positions via $iter-->

        
<xsl:choose>

            
<xsl:when test="self::element()">

                
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, 'MODE ''replace-mC-text'' :: ______ replace-mC-text - case: self::element() ______ ')" />

                
<xsl:copy copy-namespaces="no">

                    
<xsl:copy-of select="@*" />

                    
<xsl:choose>

                        
<xsl:when test="self::xsf:c">

                            
<xsl:choose>

                                
<xsl:when test="concat('[', @p, ']') = $pd-replaced-positions[$iter]">

                                    

                                    
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-mC-text'' :: (following::xsf:c)[1]/@p = ', (following::xsf:c)[1]/@p))" />

                                    

                                    
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-mC-text'' :: copied self::xsf:c[@p=', @p, ']', ' $iter=', $iter, '+', (if((following::xsf:c)[1]/@p = current()/@p) then '0' else '1')))" />

                                    
<!--only if this is the last xsf:c with this particular position info (@p), then: $iter++-->

                                    
<saxon:assign name="iter" select="$iter + (if((following::xsf:c)[1][empty(../xsf:c[2]) and (@p = current()/@p)]) then 0 else 1)" />

                                
</xsl:when>

                                
<xsl:otherwise>

                                    
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-mC-text'' :: NOTE: self:element(''', string(node-name(.)), ''')', '@p=''', @p, '''', '$pd-replaced-positions[', $iter, ']=''', $pd-replaced-positions[$iter], ''''))" />

                                    
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, 'MODE ''replace-mC-text'' :: - - - ')" />

                                    
<xsl:message select="concat('*** WARNING: whitespace from primary data not present in XML', ' (maybe removed by $heuristic-ws-search)'[$heuristic-ws-search], '!')" />

                                    
<xsl:for-each select="string-to-codepoints(substring($pd-replaced-positions[$iter], 1, 1))">

                                        
<xsl:message select="concat('*** missing: ''&amp;#', ., ';'' at position: ', $pd-replaced-positions[$iter - 1])" />

                                    
</xsl:for-each>

                                    
<xsl:message select="' - - - '" />

                                    
<saxon:assign name="iter" select="$iter + 2" />

                                
</xsl:otherwise>

                            
</xsl:choose>

                            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-mC-text'' :: self::xsf:c/@p = ''', @p, '''', ' $pd-replaced-positions[', $iter, ']=''', $pd-replaced-positions[$iter], ''''))" />

                        
</xsl:when>

                        
<xsl:otherwise>

                            
<xsl:apply-templates mode="replace-mC-text" />

                        
</xsl:otherwise>

                    
</xsl:choose>

                
</xsl:copy>

            
</xsl:when>

            
<xsl:when test="self::text()">

                

                
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, 'MODE ''replace-mC-text'' :: ______ replace-mC-text - case: self::text() ______ ')" />

                
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-mC-text'' :: self::text()=''', .,''''))" />

                
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-mC-text'' :: $pd-replaced-positions[', $iter, ']=''', $pd-replaced-positions[$iter], ''''))" />

                

                
<!--if text node is in mixed content section-->

                
<xsl:choose>

                    
<xsl:when test="bool:self-in-mC(.)">

                        
<!--if $iter in $pd-replaced-positions[$iter] is not out of range-->

                        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-mC-text'' :: mixedContent - text(): ''', ., '''', ' current $pd-replaced-positions[', $iter, ']: ''', $pd-replaced-positions[$iter], ''''))" />

                        
<xsl:if test="$pd-replaced-positions[$iter]">

                            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-mC-text'' :: $pd-replaced-positions[', $iter, ']=''', $pd-replaced-positions[$iter], ''' self::text()=''', ., ''''))" />

                            
<xsl:choose>

                                
<!--if current position's item in $pd-replaced-positions is a segment info, there cannot be any matching of mixedContent text and primary data text -->

                                
<xsl:when test="matches($pd-replaced-positions[$iter], '^\[[0-9]+\]$')">

                                    
<xsl:copy-of select="undef:ANALYZE-BUGS( 'no', 2, 'MODE ''replace-mC-text'' :: matches($pd-replaced-positions[$iter], ''^\[[0-9]+\]$'')' )" />

                                    
<xsl:choose>

                                        
<xsl:when test="matches(., '^\s*$')">

                                            
<xsl:copy-of select="undef:ANALYZE-BUGS( 'no', 2, 'MODE ''replace-mC-text'' :: matches(., ''^\s*$'') - nothing done.' )" />

                                            
<!--nothing to do-->

                                        
</xsl:when>

                                        
<xsl:otherwise>

                                            
<xsl:message select="concat('*** ERROR: $pd-replaced-positions[', $iter, '] = ''', $pd-replaced-positions[$iter], '''')" />

                                            
<xsl:message select="'*** but self::text() = ''', ., ''''" terminate="yes" />

                                        
</xsl:otherwise>

                                    
</xsl:choose>

                                
</xsl:when>

                                
<!--if current position's item in $pd-replaced-positions is a text item-->

                                
<xsl:otherwise>

                                    

                                    
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-mC-text'' :: text: ', string:int2string(string-to-codepoints(.))))" />

                                    
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-mC-text'' :: $pd-replaced-positions[$iter]: ', string:int2string(string-to-codepoints($pd-replaced-positions[$iter]))))" />

                                        

                                    
<xsl:choose>

                                        
<!--self::text() contains $pd-replaced-positions[$iter] (leading ws in self::text() ignored)-->

                                        
<xsl:when test="matches(., concat('^\s*', string:escape4regex($pd-replaced-positions[$iter]), '\s*$'))">

                                            
<xsf:c p="{if($pd-replaced-positions[$iter - 1]) then xs:integer(string:replace-all($pd-replaced-positions[$iter - 1], ('\[', '\]'), ('', ''))) else 0}" />

                                            
<!--<xsl:copy-of select="self::text()"/>-->

                                            
<xsf:c p="{(if($pd-replaced-positions[$iter - 1]) then xs:integer(string:replace-all($pd-replaced-positions[$iter - 1], ('\[', '\]'), ('', ''))) else 0) + string-length($pd-replaced-positions[$iter])}" />

                                            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, 'MODE ''replace-mC-text'' :: matches(., concat(''^\s*'', string:escape4regex($pd-replaced-positions[$iter]), ''\s*$'')) - $iter++')" />

                                            
<saxon:assign name="iter" select="$iter + 1" />

                                        
</xsl:when>

                                        
<!--self::text() contains $pd-replaced-positions[$iter] (intermingling \n* in self::text() ignored)-->

                                        
<xsl:when test="matches(., concat('^', string:infiltrate-string($pd-replaced-positions[$iter], '\n*'), '$'))">

                                            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-mC-text'' :: matches(''', ., ''', concat(''^'', string:infiltrate(''', $pd-replaced-positions[$iter], ''', ''\n*''), ''$''))'))" />

                                            
<xsf:c p="{if($pd-replaced-positions[$iter - 1]) then xs:integer(string:replace-all($pd-replaced-positions[$iter - 1], ('\[', '\]'), ('', ''))) else 0}" />

                                            
<!--<xsl:copy-of select="self::text()"/>-->

                                            
<xsf:c p="{(if($pd-replaced-positions[$iter - 1]) then xs:integer(string:replace-all($pd-replaced-positions[$iter - 1], ('\[', '\]'), ('', ''))) else 0) + string-length($pd-replaced-positions[$iter])}" />

                                            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, 'MODE ''replace-mC-text'' :: matches(., concat(''^'', string:infiltrate-string($pd-replaced-positions[$iter], ''\n*''), ''$'')) - $iter++')" />

                                            
<saxon:assign name="iter" select="$iter + 1" />

                                        
</xsl:when>

                                        
<!--self::text() contains $pd-replaced-positions[$iter] (intermingling \s* in self::text() ignored)-->

                                        
<xsl:when test="matches(., concat('^', string:infiltrate-string($pd-replaced-positions[$iter], '\s*'), '$'))">

                                            
<xsl:message select="' - - - '" />

                                            
<xsl:message select="'*** WARNING: blank within text node string not present in primary data!'" />

                                            
<xsl:message select="concat('*** missing: ''&amp;#32; '' in text node following position: ', $pd-replaced-positions[$iter - 1])" />

                                            
<xsl:message select="' - - - '" />

                                            
<xsf:c p="{if($pd-replaced-positions[$iter - 1]) then xs:integer(string:replace-all($pd-replaced-positions[$iter - 1], ('\[', '\]'), ('', ''))) else 0}" />

                                            
<!--<xsl:copy-of select="self::text()"/>-->

                                            
<xsf:c p="{(if($pd-replaced-positions[$iter - 1]) then xs:integer(string:replace-all($pd-replaced-positions[$iter - 1], ('\[', '\]'), ('', ''))) else 0) + string-length($pd-replaced-positions[$iter])}" />

                                            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, 'MODE ''replace-mC-text'' :: matches(., concat(''^'', string:infiltrate-string($pd-replaced-positions[$iter], ''\s*''), ''$'')) - $iter++')" />

                                            
<saxon:assign name="iter" select="$iter + 1" />

                                        
</xsl:when>

                                        
<!--self::text() only contains (and starts with) substring of $pd-replaced-positions[$iter]-->

                                        
<xsl:when test="starts-with($pd-replaced-positions[$iter], .)">

                                            
<!--positionsangaben-->

                                            
<xsl:variable name="matching-substring-end" select="(if($pd-replaced-positions[$iter - 1]) then xs:integer(string:replace-all($pd-replaced-positions[$iter - 1], ('\[', '\]'), ('', ''))) else 0) + string-length(.)" />

                                            
<xsf:c p="{if($pd-replaced-positions[$iter - 1]) then xs:integer(string:replace-all($pd-replaced-positions[$iter - 1], ('\[', '\]'), ('', ''))) else 0}" />

                                            
<!--<xsl:copy-of select="self::text()"/>-->

                                            
<xsf:c p="{$matching-substring-end}" />

                                            
<!--replacing the item in $pd-replaced-positions at position $iter with the same content without the starting (matching) substring-->

                                            
<saxon:assign name="pd-replaced-positions" select="insert-before( insert-before( remove($pd-replaced-positions, $iter), $iter, substring-after($pd-replaced-positions[$iter], .) ), $iter, concat('[', $matching-substring-end, ']') )" />

                                            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, 'MODE ''replace-mC-text'' :: starts-with($pd-replaced-positions[$iter], .) - $iter++')" />

                                            
<saxon:assign name="iter" select="$iter + 1" />

                                        
</xsl:when>

                                        
<xsl:otherwise>

                                            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, concat('MODE ''replace-mC-text'' :: call :: string:compare-strings(''', .,'''', ' ''', $pd-replaced-positions[$iter], ''')'))" />

                                            
<xsl:variable name="string-compare" select="string:compare-strings(., $pd-replaced-positions[$iter], '', 0)" as="xs:string+" />

                                            
<xsl:variable name="matching-substring" select="$string-compare[1]" as="xs:string" />

                                            
<xsl:variable name="rest-pd-data" select="$string-compare[2]" as="xs:string" />

                                            
<xsl:variable name="removed-leading-pd-ws" select="xs:integer($string-compare[3])" as="xs:integer" />

                                            

                                            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-mC-text'' :: $matching-substring:', $matching-substring))" />

                                            
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('MODE ''replace-mC-text'' :: $rest-pd-data:', $rest-pd-data))" />

                                            

                                            
<xsl:choose>

                                                
<xsl:when test="$matching-substring != ''">

                                                    
<!--positionsangaben-->

                                                    
<xsl:variable name="matching-substring-end" select="int:get-preceding-position() + string-length($matching-substring) + $removed-leading-pd-ws" />

                                                    
<xsf:c p="{int:get-preceding-position()}" />

                                                    
<!--<xsl:copy-of select="self::text()"/>-->

                                                    
<xsf:c p="{$matching-substring-end}" />

                                                    
<!--replacing the item in $pd-replaced-positions at position $iter with the same content without the starting (matching) substring-->

                                                    
<saxon:assign name="pd-replaced-positions" select="insert-before( insert-before( remove($pd-replaced-positions, $iter), $iter, $rest-pd-data ), $iter, concat('[', $matching-substring-end, ']') )" />

                                                    
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, 'MODE ''replace-mC-text'' :: $matching-substring != '''' - $iter++')" />

                                                    
<saxon:assign name="iter" select="$iter + 1" />

                                                
</xsl:when>

                                                
<xsl:when test="matches(., '\s+')">

                                                    
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, 'MODE ''replace-mC-text'' :: text matches ''\s+'' and no matching data from $pd-replaced-positions[$iter] was found!')" />

                                                
</xsl:when>

                                                
<xsl:otherwise>

                                                    
<xsl:message select="'-------'" />

                                                    
<xsl:message select="'*** ERROR: Template mode ''replace-mC-text'' - text does not match regex!'" />

                                                    
<xsl:message select="concat('*** self::text() = ''', ., '''')" />

                                                    
<xsl:message select="concat('*** string:infiltrate-string($pd-replaced-positions[$iter], ''\s*'') = ''', string:infiltrate-string($pd-replaced-positions[$iter], '\s*'), '''')" />

                                                    
<xsl:message select="concat('*** $pd-replaced-positions[', $iter - 1, '] = ''', $pd-replaced-positions[$iter - 1], '''')" />

                                                    
<xsl:message select="concat('*** $pd-replaced-positions[', $iter, '] = ''', $pd-replaced-positions[$iter], '''')" terminate="yes" />

                                                
</xsl:otherwise>

                                            
</xsl:choose>

                                        
</xsl:otherwise>

                                    
</xsl:choose>

                                
</xsl:otherwise>

                            
</xsl:choose>

                        
</xsl:if>

                    
</xsl:when>

                    
<xsl:otherwise>

                        
<xsl:message select="'template mode=''replace-mC-text'' - text in non-mC context detected!'" terminate="yes" />

                    
</xsl:otherwise>

                
</xsl:choose>

            
</xsl:when>

            
<xsl:when test="self::comment() | self::processing-instruction()">

                
<xsl:copy-of select="." />

            
</xsl:when>

        
</xsl:choose>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### END: mode=''replace-mC-text'' ###')" />

    
</xsl:template>

    

    

    
         <xd:doc>

        
<xd:short><p>The template performs a copy of $segmentation-base (input XML with textual content replaced by position information) and returns position info for empty elements.</p></xd:short>

    
</xd:doc>


    
<xsl:template match="element() | text() | processing-instruction() | comment()" mode="replace-empty-elements">

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### START: mode=''replace-empty-elements'' ###')" />

        
<xsl:choose>

            
<xsl:when test="self::text() | self::processing-instruction() | self::comment()">

                
<xsl:copy-of select="." />

            
</xsl:when>

            
<xsl:when test="self::element()">

                
<xsl:copy>

                    
<xsl:copy-of select="@*" />

                    
<xsl:choose>

                        
<xsl:when test="empty(text()|element()) and not(self::xsf:c)">

                            
<xsl:choose>

                                
<xsl:when test="(xs:integer((preceding::xsf:c)[last()]/@p), 0)[1] = xs:integer((following::xsf:c)[1]/@p)">

                                    
<xsf:c p="{(following::xsf:c)[1]/@p}" />

                                
</xsl:when>

                                
<xsl:otherwise>

                                    
<xsl:choose>

                                        
<xsl:when test="empty((preceding::xsf:c)[last()]/@p) and empty((following::xsf:c)[1]/@p)">

                                            
<xsl:message select="concat('*** TEMPL mode :: replace-empty-elements - empty element between ', ((preceding::xsf:c)[last()]/@p, '')[1], ' and ', (following::xsf:c)[1]/@p)" terminate="yes" />

                                        
</xsl:when>

                                        
<xsl:when test="empty((preceding::xsf:c)[last()]/@p)">

                                            
<xsf:c p="{(following::xsf:c)[1]/@p}" />

                                        
</xsl:when>

                                        
<xsl:when test="empty((following::xsf:c)[1]/@p)">

                                            
<xsf:c p="{(preceding::xsf:c)[last()]/@p}" />

                                        
</xsl:when>

                                        
<xsl:when test="matches( substring($primary-data-string, (xs:integer((preceding::xsf:c)[last()]/@p), 0)[1] + 1, (xs:integer((following::xsf:c)[1]/@p), 0)[1] - (xs:integer((preceding::xsf:c)[last()]/@p), 0)[1]), '^\s+$' )">

                                            
<xsl:choose>

                                                
<xsl:when test="matches(preceding-sibling::node()[1], '\s+') and string-length(preceding-sibling::node()[1]) le ( (xs:integer((following::xsf:c)[1]/@p), 0)[1] - (xs:integer((preceding::xsf:c)[last()]/@p), 0)[1])">

                                                    
<xsf:c p="{(preceding::xsf:c)[last()]/@p + string-length(preceding-sibling::node()[1])}" />

                                                
</xsl:when>

                                                
<xsl:otherwise>

                                                    
<xsf:c p="{(preceding::xsf:c)[last()]/@p}" />

                                                
</xsl:otherwise>

                                            
</xsl:choose>

                                        
</xsl:when>

                                        
<xsl:otherwise>

                                            
<xsl:message select="concat('*** TEMPL mode :: replace-empty-elements - empty element between ', ((preceding::xsf:c)[last()]/@p, '')[1], ' and ', (following::xsf:c)[1]/@p)" terminate="yes" />

                                        
</xsl:otherwise>

                                    
</xsl:choose>

                                 
</xsl:otherwise>

                            
</xsl:choose>

                        
</xsl:when>

                        
<xsl:otherwise>

                            
<xsl:apply-templates mode="replace-empty-elements" />

                        
</xsl:otherwise>

                    
</xsl:choose>

                
</xsl:copy>

            
</xsl:when>

        
</xsl:choose>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### END: mode=''replace-empty-elements'' ###')" />

    
</xsl:template>

    

    

    
         <xd:doc>

        
<xd:short><p>The template performs a copy of $segmentation-base (input XML with textual content replaced by position information) without positioning elements.</p></xd:short>

        
<xd:param name="namespace-uri">determines the namespace whose elements shall be copied.</xd:param>

    
</xd:doc>


    
<xsl:template match="element() | text() | processing-instruction() | comment()" mode="copy-segmentation-base">

        
<xsl:param name="namespace-uri" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### START: mode=''copy-segmentation-base'' ###')" />

        
<xsl:choose>

            
<xsl:when test="self::text() | self::processing-instruction() | self::comment()">

                
<xsl:copy-of select="." />

            
</xsl:when>

            
<xsl:when test="self::element()">

                
<xsl:choose>

                    
<xsl:when test="(not(self::xsf:c) and (if($namespace-uri = 'all') then true() else (namespace-uri() = $namespace-uri))) and (if($all-layer) then not(index-of((for $ID in $segments4elements-in-all-layer//@generated-IDs return tokenize($ID, ' ')), generate-id()) &gt; 0) else true())">

                        
<xsl:copy>

                            
<xsl:copy-of select="@* except @xsi:schemaLocation" />

                            
<xsl:attribute name="xsf:segment" select="key('segment-by-positions', concat(descendant::xsf:c[1]/@p, '-', descendant::xsf:c[last()]/@p), $segmentation)/@xml:id" />

                            
<xsl:apply-templates mode="copy-segmentation-base">

                                
<xsl:with-param name="namespace-uri" select="$namespace-uri" />

                            
</xsl:apply-templates>

                        
</xsl:copy>

                    
</xsl:when>

                    
<xsl:otherwise>

                        
<xsl:apply-templates mode="copy-segmentation-base">

                            
<xsl:with-param name="namespace-uri" select="$namespace-uri" />

                        
</xsl:apply-templates>

                    
</xsl:otherwise>

                
</xsl:choose>

            
</xsl:when>

        
</xsl:choose>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### END: mode=''copy-segmentation-base'' ###')" />

    
</xsl:template>

    

    

    
         <xd:doc>

        
<xd:short><p>Template for removing pure whitespace text nodes from input XML.</p></xd:short>

        
<xd:detail>

            
<p>This template removes all pure whitespace text nodes from the input and thus prepares it for a heuristical determination of whitespace positions.</p>

        
</xd:detail>

    
</xd:doc>


    
<xsl:template match="document-node() | element() | text() | attribute() | processing-instruction() | comment()" mode="remove-ws-text-nodes">

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### START: mode=''remove-ws-text-nodes'' ###')" />

        
<xsl:choose>

            
<xsl:when test="self::element()"><xsl:copy><xsl:copy-of select="@*" /><xsl:apply-templates mode="remove-ws-text-nodes" /></xsl:copy></xsl:when>

            
<xsl:when test="self::text()"><xsl:if test="matches(., '[^\s]') or not(bool:self-in-mC(.))"><xsl:value-of select="." /></xsl:if></xsl:when>

            
<xsl:when test="self::comment() | self::processing-instruction()"><xsl:copy-of select="." /></xsl:when>

        
</xsl:choose>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### END: mode=''remove-ws-text-nodes'' ###')" />

    
</xsl:template>

    

    

    
         <xd:doc>

        
<xd:short><p>Recursive copy of elements descending the context node elements are copied iff they are in the provided namespace ($uri)</p></xd:short>

        
<xd:param name="uri">Defines the namespace uri whose elements a copied during the recursive template call</xd:param>

    
</xd:doc>


    
<xsl:template name="copy-nodes-by-namespace-uri" as="element()*">

        
<xsl:param name="uri" as="xs:anyURI*" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### START: name=''copy-nodes-by-namespace-uri'' ###')" />

        
<xsl:variable name="elem-namespace" select="namespace-uri(.)" as="xs:anyURI" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('TEMPL ''copy-nodes-by-namespace-uri'' :: ', generate-id(), tokenize($segments4elements-in-all-layer//@generated-IDs, ' '), ' - ', empty(tokenize($segments4elements-in-all-layer//@generated-IDs, ' ')[.=current()/generate-id()])))" />

        
<xsl:choose>

            
<xsl:when test="$elem-namespace=$uri and name()!='' and (if($include-all-layer) then empty(tokenize(string-join($segments4elements-in-all-layer//@generated-IDs, ' '), ' ')[.=current()/generate-id()]) else true())">

                
<xsl:element name="{string(node-name(.))}" namespace="{$elem-namespace}">

                    
<xsl:if test="if(exists(descendant::element()|descendant::text())) then true() else bool:include-empty-element(prefix-from-QName(node-name(.)))">

                        
<xsl:variable name="segmentID" select="key('segment-by-positions', concat(descendant::xsf:c[1]/@p, descendant::xsf:c[last()]/@p))/@xml:id" />

                        
<xsl:if test="$segmentID">

                            
<xsl:attribute name="xsf:segment" select="$segmentID" namespace="http://www.xstandoff.net/2009/xstandoff/1.1" />

                        
</xsl:if>

                    
</xsl:if>

                    
<xsl:copy-of select="@*[name()!='lang' and name()!='xsi:schemaLocation']" />

                    
<xsl:if test="exists(@lang)">

                        
<xsl:attribute name="xml:lang" select="@lang" />

                    
</xsl:if>

                    
<xsl:for-each select="*">

                        
<xsl:call-template name="copy-nodes-by-namespace-uri">

                            
<xsl:with-param name="uri" select="$uri" as="xs:anyURI*" />

                        
</xsl:call-template>

                    
</xsl:for-each>

                
</xsl:element>

            
</xsl:when>

            
<xsl:otherwise>

                
<xsl:for-each select="*">

                    
<xsl:call-template name="copy-nodes-by-namespace-uri">

                        
<xsl:with-param name="uri" select="$uri" as="xs:anyURI*" />

                    
</xsl:call-template>

                
</xsl:for-each>

            
</xsl:otherwise>

        
</xsl:choose>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### END: name=''copy-nodes-by-namespace-uri'' ###')" />

    
</xsl:template>

    

    

    
<!-- Extraction of primary data from XML input on the basis of its textual content -->

    

    
         <xd:doc>

        
<xd:short>

            
<p>Normalization of XML data, see also: SVN/software/tools/trunk/normalize2.xsl</p>

            
<p>changed version of the (invalid) original from http://dpawson.co.uk/xsl/sect2/N8321.html#d12364e18</p>

        
</xd:short>

    
</xd:doc>


    
<xsl:template name="normalize">

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### START: name=''normalize'' ###')" />

        
<xsl:choose>

            
<xsl:when test="self::element()">

                
<xsl:copy>

                    
<xsl:for-each select="attribute()|comment()|text()|processing-instruction()|element()">

                        
<xsl:call-template name="normalize" />

                    
</xsl:for-each>

                
</xsl:copy>

            
</xsl:when>

            
<xsl:when test="self::attribute()">

                
<xsl:choose>

                    
<xsl:when test="not( prefix-from-QName(node-name(.)) )">

                        
<xsl:attribute name="{local-name(.)}" select="if(. instance of xs:string) then normalize-space(.) else ." />

                    
</xsl:when>

                    
<xsl:otherwise>

                        
<xsl:attribute name="{name(.)}" namespace="{namespace-uri(.)}" select="if(. instance of xs:string) then normalize-space(.) else ." />

                    
</xsl:otherwise>

                
</xsl:choose>

            
</xsl:when>

            
<xsl:when test="self::comment()">

                
<xsl:comment select="normalize-space(.)" />

            
</xsl:when>

            
<xsl:when test="self::text()">

                
<xsl:value-of select="normalize-space(.)" />

            
</xsl:when>

            
<xsl:when test="self::processing-instruction()">

                
<xsl:processing-instruction name="{local-name(.)}" select="normalize-space(.)" />

            
</xsl:when>

            
<xsl:otherwise>

                
<!--this case refers to the document root-->

                
<xsl:for-each select="attribute()|comment()|text()|processing-instruction()|element()">

                    
<xsl:call-template name="normalize" />

                
</xsl:for-each>

            
</xsl:otherwise>

        
</xsl:choose>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### END: name=''normalize'' ###')" />

    
</xsl:template>

    

    

    
         <xd:doc>

        
<xd:short>

            
<p>

                This template generates a text on the basis of the textual content of the provided $XMLdata.

                The text serves as primary data and therefore as a reference of the start and end position of elements.

            
</p>

        
</xd:short>

    
</xd:doc>


    
<xsl:template name="build-primary-data-from-XML" as="xs:string">

        
<xsl:param name="XMLdata" as="node()+" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### START: name=''build-primary-data-from-XML'' ###')" />

        
<!--saving extracted textual content from XML data in $textData-->

        
<xsl:variable name="textData" as="xs:string*">

            
<xsl:for-each select="$XMLdata//(text()|*[local-name()='p'])">

                
<xsl:choose>

                    
<!--returning text nodes unchanged-->

                    
<xsl:when test="self::text()">

                        
<xsl:value-of select="." />

                    
</xsl:when>

                    
<!--inserting line break for <p>-elements (paragraphs)-->

                    
<xsl:otherwise>

                        
<xsl:if test="position()!=1">

                            
<xsl:text>

                            
</xsl:text>

                        
</xsl:if>

                    
</xsl:otherwise>

                
</xsl:choose>

            
</xsl:for-each>

        
</xsl:variable>

        
<xsl:if test="empty($textData)">

            
<xsl:message select="' *** ATTENTION: there is no textual content in XML input to generate primary data!'" />

        
</xsl:if>

        
<!--processing sequence of strings-->

        
<xsl:variable name="tempTextData">

            
<xsl:for-each select="$textData">

                
<xsl:variable name="pos" select="position()" as="xs:integer" />

                
<!--conditions for returning a whitespace before a string;

                    string-to-codepoints for " and '
-->

                
<xsl:if test="$pos!=1">

                    
<xsl:variable name="stringBefore" select="$textData[$pos - 1]" as="xs:string" />

                    
<!--conditions for returning a whitespace before the current string-->

                    
<xsl:choose>

                        
<xsl:when test="string-length(.)=1">

                            
<!--conditions to be fulfilled to return a blank-->

                            
<xsl:if test="(:###vor Satz- und Sonderzeichen soll kein Leerzeichen ausgegeben werden###:) not(matches(., '[.,;:!\?%)\]*´`°\|}]')) and (:###auch nicht vor Zeichen, denen eine öffnende Klammer vorausgeht###:) not(matches($stringBefore, '[(\[{]')) and (:###falls der aktuelle und der vorhergehende String ein Klitikon bilden wird kein Leerzeichen ausgegeben###:) not(bool:twoStringsFormClitic($stringBefore, .)) and (:###falls der aktuelle String ein - ist, wird zwischen versch. Fällen unterschieden, ob ein Leerzeichen ausgegeben wird###:) (if(.='-' and matches($textData[$pos+1], ',|und|oder|and|or')) then false() else true()) and (:###falls der aktuelle String ein ' ist und das vorhergehende oder nachfolgende Zeichen ein s (Genitiv), wird kein Leerzeichen ausgegeben###:) (if(deep-equal(string-to-codepoints(.), 39) and ($textData[$pos + 1]='s' or substring($stringBefore, string-length($stringBefore))='s')) then false() else true()) and (:###falls der aktuelle String ein ' oder &quot; ist, und es gemessen an allen vorhergehenden gleichen Zeichen an gerader Position steht, wird davor kein Leerzeichen ausgegeben###:) (if(deep-equal(string-to-codepoints(.), 39) or deep-equal(string-to-codepoints(.), 34)) then ((floor(count($textData[position() &lt; $pos][.=current()]) div 2)) = (count($textData[position() &lt; $pos][.=current()]) div 2)) else true()) and (:###falls der vorhergehende String ein doppeltes ' ('') ist und er gemessen an allen vorhergehenden gleichen Strings an ungerader Position steht, wird vor dem aktuellen Zeichen kein Leerzeichen ausgegeben###:) (if(deep-equal(string-to-codepoints($stringBefore), (39, 39))) then ((floor(count($textData[position() &lt; ($pos - 1)][.=$stringBefore]) div 2)) = (count($textData[position() &lt; ($pos - 1)][.=$stringBefore]) div 2)) else true()) and (:###falls es sich beim aktuellen Zeichen um € oder $ handelt und davor eine Zahl steht, wird kein Leerzeichen ausgegeben###:) (if(matches(substring($stringBefore, string-length($stringBefore)), '[0-9]')) then not(matches(current(), '[$€]')) else true()) and (:###falls es sich beim aktuellen Zeichen um eine Zahl handelt und davor ein $ oder € steht, wird kein Leerzeichen ausgegeben###:) (if(matches(substring(., string-length(.)), '[0-9]')) then not(matches($stringBefore, '[$€]')) else true()) and (:###falls es sich beim vorhergehenden oder aktuellen Zeichen um einen Zeilenumbruch handelt, wird kein Leerzeichen ausgegeben###:) not(deep-equal(string-to-codepoints($stringBefore), 10) or deep-equal(string-to-codepoints(.), 10))">

                                
<!--returning blank-->

                                
<xsl:value-of select="' '" />

                            
</xsl:if>

                        
</xsl:when>

                        
<xsl:otherwise>

                            
<xsl:choose>

                                
<xsl:when test="string-length($stringBefore) = 1">

                                    
<!--conditions have to be fulfilled to return a blank-->

                                    
<xsl:if test="(:###Vor Zeichen, denen eine öffnende Klammer vorausgeht, soll kein Leerzeichen ausgegeben werden###:) not(matches($stringBefore, '[(\[{]')) and (:###falls der vorhergehende String ein ' ist und das aktuelle Zeichen ein s (Genitiv), wird kein Leerzeichen ausgegeben###:) (if(deep-equal(string-to-codepoints($stringBefore), 39) and .='s') then false() else true()) and (:###falls der vorhergehende String ein ' oder &quot; ist, und es gemessen an allen vorhergehenden gleichen Zeichen an gerader Position steht, wird vor dem aktuellen String kein Leerzeichen ausgegeben###:) (if(deep-equal(string-to-codepoints($stringBefore), 39) or deep-equal(string-to-codepoints($stringBefore), 34)) then ((floor(count($textData[position() &lt; $pos][.=$stringBefore]) div 2)) = (count($textData[position() &lt; $pos][.=$stringBefore]) div 2)) else true()) and (:###falls der aktuelle String ein doppeltes ' ('') ist und er gemessen an allen vorhergehenden gleichen Strings an gerader Position steht, wird davor kein Leerzeichen ausgegeben###:) (if(deep-equal(string-to-codepoints(.), (39, 39))) then ((floor(count($textData[position() &lt; $pos][.=current()]) div 2)) = (count($textData[position() &lt; $pos][.=current()]) div 2)) else true()) and (:###falls es sich beim aktuellen Zeichen eine Zahl handelt und davor ein $ oder € steht, wird kein Leerzeichen ausgegeben###:) (if(matches(substring(., string-length(.)), '[0-9]')) then not(matches($stringBefore, '[$€]')) else true()) and (:###falls es sich beim vorhergehenden oder aktuellen Zeichen um einen Zeilenumbruch handelt, wird kein Leerzeichen ausgegeben###:) not(deep-equal(string-to-codepoints($stringBefore), 10) or deep-equal(string-to-codepoints(.), 10))">

                                        
<!--returning blank-->

                                        
<xsl:value-of select="' '" />

                                    
</xsl:if>

                                
</xsl:when>

                                
<xsl:otherwise>

                                    
<!--conditions have to be fulfilled to return a blank-->

                                    
<xsl:if test="(:### aktueller String sollte nicht 's sein ###:) not((string-length(.) = 2) and (deep-equal(string-to-codepoints(substring(., 1, 1)), 39) and substring(., 2, 1)='s')) and (:###falls der aktuelle String ein doppeltes ' ('') ist und er gemessen an allen vorhergehenden gleichen Strings an gerader Position steht, wird davor kein Leerzeichen ausgegeben###:) (if(deep-equal(string-to-codepoints(.), (39, 39))) then ((floor(count($textData[position() &lt; $pos][.=current()]) div 2)) = (count($textData[position() &lt; $pos][.=current()]) div 2)) else true()) and (:###falls der vorhergehende String ein doppeltes ' ('') ist und er gemessen an allen vorhergehenden gleichen Strings an ungerader Position steht, wird vor dem aktuellen Zeichen kein Leerzeichen ausgegeben###:) (if(deep-equal(string-to-codepoints($stringBefore), (39, 39))) then ((floor(count($textData[position() &lt; ($pos - 1)][.=$stringBefore]) div 2)) != (count($textData[position() &lt; ($pos - 1)][.=$stringBefore]) div 2)) else true()) and (:###falls es sich beim vorhergehenden oder aktuellen Zeichen um einen Zeilenumbruch handelt, wird kein Leerzeichen ausgegeben###:) not(deep-equal(string-to-codepoints($stringBefore), 10) or deep-equal(string-to-codepoints(.), 10))">

                                        
<!--returning blank-->

                                        
<xsl:value-of select="' '" />

                                    
</xsl:if>

                                
</xsl:otherwise>

                            
</xsl:choose>

                        
</xsl:otherwise>

                    
</xsl:choose>

                
</xsl:if>

                
<!--returning current string itself-->

                
<xsl:value-of select="." />

            
</xsl:for-each>

        
</xsl:variable>

        
<xsl:value-of select="string-join($tempTextData, '')" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### TEMPLATE ### END: name=''build-primary-data-from-XML'' ###')" />

    
</xsl:template>

    

    

    
         <xd:doc>

        
<xd:short>

            
<p>Testing whether or not two strings ($string1 und $string2) form a clitic together. </p>

        
</xd:short>

    
</xd:doc>


    
<xsl:function name="bool:twoStringsFormClitic" as="xs:boolean">

        
<xsl:param name="string1" as="xs:string" />

        
<xsl:param name="string2" as="xs:string" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''bool:twoStringsFormClitic'' ###')" />

        
<!--cf. Nübling, Damaris (1992): Klitika im Deutschen: Schriftsprache, Umgangssprache, alemannische Dialekte. Gunter Narr Verlag, S. 160-->

        
<xsl:choose>

            
<xsl:when test="matches($string1, '[Bb]ei|[Ii]|[Aa]|[Vv]o')[$string2='m']">

                
<xsl:copy-of select="true()" />

            
</xsl:when>

            
<xsl:when test="matches($string1, '[Zz]u')[matches($string2, '[mr]')]">

                
<xsl:copy-of select="true()" />

            
</xsl:when>

            
<xsl:when test="matches($string1, '[Aa]n|[Ii]n|[Nn]eben|[Uu]m|[Dd]urch')[$string2='s']">

                
<xsl:copy-of select="true()" />

            
</xsl:when>

            
<xsl:when test="matches($string1, '[Aa]uf|[Vv]or')[matches($string2, '[ms]')]">

                
<xsl:copy-of select="true()" />

            
</xsl:when>

            
<xsl:when test="matches($string1, '[Ff]ür')[matches($string2, '[ns]')]">

                
<xsl:copy-of select="true()" />

            
</xsl:when>

            
<xsl:when test="matches($string1, '[Üü]ber|[Uu]nter|[Hh]inter')[matches($string2, '[mns]')]">

                
<xsl:copy-of select="true()" />

            
</xsl:when>

            
<xsl:otherwise>

                
<xsl:copy-of select="false()" />

            
</xsl:otherwise>

        
</xsl:choose>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''bool:twoStringsFormClitic'' ###')" />

    
</xsl:function>

    

    
<!-- End of templates/functions for extraction of primary data from XML input on the basis of its textual content-->

    

    

    
<!-- Other functions -->

    

    
         <xd:doc>

        
<xd:short><p>Tests whether a node (text() or element()) is in a mixed content section</p></xd:short>

        
<xd:param name="self">Element or text node for which a test is run whether $self is located within a mixed content section</xd:param>

    
</xd:doc>


    
<xsl:function name="bool:self-in-mC" as="xs:boolean">

        
<xsl:param name="self" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''bool:self-in-mC'' ###')" />

        
<xsl:copy-of select="if($self/self::text()) then exists($self/preceding-sibling::element()|$self/following-sibling::element()) else exists($self/preceding-sibling::text()|$self/following-sibling::text())" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''bool:self-in-mC'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc>

        
<xd:short><p>Function for getting names of elements from a specific namespace</p></xd:short>

        
<xd:param name="namespaces">Namespace URIs whose included elements shall be enlisted in declared attribute output format</xd:param>

    
</xd:doc>


    
<xsl:function name="attr:return-atts-for-elems-from-namespace" as="attribute()*">

        
<xsl:param name="namespaces" as="xs:anyURI*" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''attr:return-atts-for-elems-from-namespace'' ###')" />

        
<xsl:for-each select="$namespaces">

            
<xsl:variable name="thisNamespaceURI" select="." as="xs:anyURI?" />

            
<xsl:if test="$thisNamespaceURI=xs:anyURI('http://www.xstandoff.net/2009/all')">

                
<xsl:attribute name="{string(QName($thisNamespaceURI, 'all'))}" select="1" namespace="{$thisNamespaceURI}" />

            
</xsl:if>

            
<xsl:for-each select="distinct-values(key('elem-by-namespace-uri', $thisNamespaceURI, $virtual-root-node)/local-name(.))">

                
<xsl:attribute name="{string(QName($thisNamespaceURI, if($thisNamespaceURI=xs:anyURI('http://www.xstandoff.net/2009/all')) then concat('all:', .) else .))}" select="1" namespace="{$thisNamespaceURI}" />

            
</xsl:for-each>

        
</xsl:for-each>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''attr:return-atts-for-elems-from-namespace'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc>

        
<xd:short><p>Returns the position (start and end) of the first occurence of a substring in string</p></xd:short>

        
<xd:param name="string">Input string in which a certain substring could be found</xd:param>

        
<xd:param name="substring">Substring that is expected and searched within the input string</xd:param>

    
</xd:doc>


    
<xsl:function name="int:substring-positions" as="xs:integer*">

        
<xsl:param name="string" as="xs:string" />

        
<xsl:param name="substring" as="xs:string" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''int:substring-positions'' ###')" />

        
<xsl:choose>

            
<xsl:when test="contains($string, $substring)">

                
<xsl:choose>

                    
<!--the last char of $substring is present as the first char in $string, therefore a special condition has to be fulfilled to avoid 

                    problems with substring() and string-length(). There might be problems for $substring of length 1, whereas $string has the 

                    same char as second char.
-->

                    
<xsl:when test="if(starts-with($string, $substring)) then ( if(string-length($substring) = 1) then ( if(starts-with(substring($string, 2), $substring)) then true() else false() ) else false() ) else false()">

                        
<xsl:sequence select="string-length(substring-before($string, $substring)) + 1, string-length(substring-before($string, $substring)) + string-length($substring) + 1" />

                    
</xsl:when>

                    
<xsl:otherwise>

                        
<xsl:sequence select="string-length(substring-before($string, $substring)), string-length(substring-before($string, $substring)) + string-length($substring)" />

                    
</xsl:otherwise>

                
</xsl:choose>

            
</xsl:when>

            
<xsl:otherwise>

                
<xsl:choose>

                    
<xsl:when test="$pd-check = 'strict'">

                        
<!--no additional whitespaces or indents allowed in the middle of terminal text nodes (only at their boundaries)-->

                        
<xsl:message select="'*** ERROR: int:substring-positions() detected primary data mismatch!'" />

                        
<xsl:message select="'*** Mismatching substring: '" />

                        
<xsl:message select="concat('''', $substring,'''')" />

                        
<xsl:message select="concat('*** ATTENTION: $pd-check=''', $pd-check, ''' ', (if($pd-check != 'lax') then '- try lower level (e.g.: pd-check=lax)' else '- provide value ''create'' for $primary-data to automatically create a primary data file'))" terminate="yes" />

                    
</xsl:when>

                    
<xsl:otherwise>

                        
<!--indents and additional whitespaces allowed within terminal text nodes-->

                        
<xsl:variable name="modified-substring" select="string:replace-all( $substring, ('\\', '\|', '\*', '\?', '\[', '\]', '\{', '\}', '\-', '\+', '\.', '\(', '\)', '^\s+', '\s+$', '\s+'), ('\\\\', '\\|', '\\*', '\\?', '\\[', '\\]', '\\{', '\\}', '\\-', '\\+', '\\.', '\\(', '\\)', '\\s*', '', '\\s+') )" as="xs:string" />

                        
<!--regex too greedy for tailing whitespaces -> segment end too wide-->

                        
<!--<xsl:variable name="modified-substring" select="string:replace-all($substring, ('^\s+', '\s+$', '\s+'), ('\\s*', '\\s*', '\\s+') )" as="xs:string"/>-->

                        
<xsl:choose>

                            
<!--if $string contains modified $substring; $substring modified to be used as a regular expression (replaced leading, tailing and inner whitespaces by \s* or \s+).-->

                            
<xsl:when test="matches( $string, $modified-substring)">

                                
<!--if $string contains $substring whereas whitepsace sequences in $substring are replaced by regex placeholders-->

                                
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, 'FUNC ''int:substring-positions'' :: DEV-NOTE: Terminal text node includes additional whitespaces.')" />

                                
<!--<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('FUNC ''int:substring-positions'' :: DEV-NOTE: ', '$string: #', $string, '#'))"/>-->

                                
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('FUNC ''int:substring-positions'' :: DEV-NOTE: ', '$substring: #', $substring, '#'))" />

                                
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('FUNC ''int:substring-positions'' :: DEV-NOTE: ', '$modified-substring:', $modified-substring))" />

                                

                                
<!--###############################################################################-->

                                
<xsl:analyze-string select="$string" regex="{if(contains($string, '\n')) then concat('.*(', $modified-substring, ').*') else concat('^.*(', $modified-substring, ').*$')}" flags="s">

                                    
<!--.* greedy machen, damit sie auch leading und tailing ws einschließen oder \\s* ungreedy machen-->

                                    
<!--was bei zwei Vorkommen? nur erstes berücksichtigen-->

                                    
<xsl:matching-substring>

                                        
<!--für das erste Vorkommen des substrings-->

                                        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('FUNC ''int:substring-positions'' :: DEV-NOTE: derived position in string: ', string:int2string(int:substring-positions($string, regex-group(1)))))" />

                                        
<xsl:copy-of select="int:substring-positions($string, regex-group(1))" />

                                    
</xsl:matching-substring>

                                
</xsl:analyze-string>

                                
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, 'FUNC ''int:substring-positions'' :: to be worked on')" />

                                
<!--###############################################################################-->

                            
</xsl:when>

                            
<xsl:otherwise>

                                
<xsl:message select="'*** ERROR: int:substring-positions() detected primary data mismatch!'" />

                                

                                
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('FUNC ''int:substring-positions'' :: $string: ''', $string, ''''))" />

                                
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('FUNC ''int:substring-positions'' :: $modified-substring: ''', $modified-substring, ''''))" />

                                
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 2, concat('FUNC ''int:substring-positions'' :: $substring: ''', $substring, ''''))" />

                                

                                
<xsl:message select="'*** Mismatching substring: '" />

                                
<xsl:message select="concat('''', $substring,'''')" />

                                
<xsl:message select="concat('*** ATTENTION: $pd-check=''', $pd-check, ''' ', (if($pd-check != 'lax') then '- try lower level (e.g.: pd-check=lax)' else '- provide value ''create'' for $primary-data to create an automatic primary data file'))" terminate="yes" />

                            
</xsl:otherwise>

                        
</xsl:choose>

                    
</xsl:otherwise>

                
</xsl:choose>

            
</xsl:otherwise>

        
</xsl:choose>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''int:substring-positions'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc>

        
<xd:short><p>This function replaces all instances from the regex sequence (regexSEQ) by the corresponding substitution values (same position in replaceSEQ)</p></xd:short>

        
<xd:param name="inputString">Input string whose corresponding characters are to be replaced</xd:param>

        
<xd:param name="regexSEQ">Sequence of regular expressions used to find substrings in the input</xd:param>

        
<xd:param name="replaceSEQ">Sequence of substituting strings which shall replace matching regex strings in the input string</xd:param>

    
</xd:doc>


    
<xsl:function name="string:replace-all" as="xs:string?">

        
<xsl:param name="inputString" as="xs:string" />

        
<xsl:param name="regexSEQ" as="xs:string+" />

        
<xsl:param name="replaceSEQ" as="xs:string+" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''string:replace-all'' ###')" />

        
<xsl:if test="empty($regexSEQ) or empty($replaceSEQ)">

            
<xsl:message select="'*** ERROR: string:replace-all() - parameter mismatch!'" />

        
</xsl:if>

        
<xsl:value-of select="if($regexSEQ[2]) then string:replace-all(replace($inputString, $regexSEQ[1], $replaceSEQ[1]), subsequence($regexSEQ, 2), subsequence($replaceSEQ, 2)) else replace($inputString, $regexSEQ[1], $replaceSEQ[1])" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''string:replace-all'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc>

        
<xd:short><p>Copy of elements into an inline annotation by reference to segments</p></xd:short>

        
<xd:param name="segments">XSF segments that form the basis for the resulting inline annotation</xd:param>

    
</xd:doc>


    
<xsl:function name="undef:segments2inline">

        
<xsl:param name="segments" as="element()*" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''undef:segments2inline'' ###')" />

        
<!--finding segments without "ancestor" (by @start and @end information)-->

        
<xsl:for-each select="$segments[for $this-seg in . return empty($segments[@xml:id != $this-seg/@xml:id][number(@start) &lt;= number($this-seg/@start) and number(@end) &gt;= number($this-seg/@end)])]">

            
<xsl:element name="{concat('all:', @local-name)}">

                
<xsl:attribute name="xsf:segment" select="@xml:id" />

                
<xsl:copy-of select="(@* except (@xml:id, @local-name, @generated-IDs, @start, @end, @xsi:schemaLocation)), (:####going on copying next elements####:) undef:segments2inline(key('elem-by-id', current()/@xml:id, $segments4elements-in-all-layer)/following-sibling::* [( number(@start) &gt;= number(current()/@start) and number(@end) &lt;= number(current()/@end) )])" />

            
</xsl:element>

        
</xsl:for-each>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''undef:segments2inline'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc>

        
<xd:short><p>Testing whether to include an empty element using stylesheet parameter $levels-empty-elements </p></xd:short>

        
<xd:param name="ns-prefix">Namespace prefix(es) of empty elements which are to be included in XSF</xd:param>

    
</xd:doc>


    
<xsl:function name="bool:include-empty-element" as="xs:boolean">

        
<xsl:param name="ns-prefix" as="xs:string*" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''bool:include-empty-element'' ###')" />

        
<xsl:copy-of select="if($levels-empty-elements!='#all') then (index-of(tokenize($levels-empty-elements, ','), ($ns-prefix, '')[1]) &gt; 0) else true()" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''bool:include-empty-element'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc>

        
<xd:short><p>A valid ID is returned on the basis of the value of the input-string; necessary changes being made</p></xd:short>

        
<xd:param name="input-string">As the name says, this is the string which is made xs:ID conform</xd:param>

    
</xd:doc>


    
<xsl:function name="string:ID-comform" as="xs:string">

        
<xsl:param name="input-string" as="xs:string" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''string:ID-comform'' ###')" />

        
<xsl:copy-of select="if(matches($input-string, '^[_a-zA-Z][-a-zA-Z0-9\.äöüÄÖÜß_]*$')) then $input-string else ( if(matches(substring($input-string, 1, 1), '[_A-Za-z]')) (:##in case that starting char of $input-String is valid with respect to type xs:ID##:) then string:ID-comform(replace($input-string, '[^-a-zA-Z0-9\.äöüÄÖÜß_]', '_')) (:##in case that starting char of $input-String is not valid with respect to type xs:ID##:) else string:ID-comform(concat('_', $input-string)) )" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''string:ID-comform'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc><xd:short><p>Returning messages containing stylesheet parameters and their supplied values</p></xd:short></xd:doc>


    
<xsl:function name="undef:param-messages">

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''undef:param-messages'' ###')" />

        
<xsl:message select="'--------------------'" />

        
<xsl:message select="' Provided stylesheet parameters:'" />

        
<xsl:message select="concat(' primary-data=''', $primary-data, '''')" />

        
<xsl:message select="concat(' virtual-root=''', $virtual-root, '''')" />

        
<xsl:message select="concat(' meta-root=''', $meta-root, '''')" />

        
<xsl:message select="concat(' local-xsd=', $local-xsd)" />

        
<xsl:message select="concat(' file-in-one-layer=', $file-in-one-layer)" />

        
<xsl:message select="concat(' copy-primary-data-to-xsf=', $copy-primary-data-to-xsf)" />

        
<xsl:message select="concat(' include-optional-elements=', $include-optional-elements)" />

        
<xsl:message select="concat(' include-ws-segments=', $include-ws-segments)" />

        
<xsl:message select="concat(' levels-empty-elements=''', $levels-empty-elements, '''')" />

        
<xsl:message select="concat(' all-layer=', $all-layer)" />

        
<xsl:message select="concat(' xsfVersion=''', $xsfVersion, '''')" />

        
<xsl:message select="concat(' pd-check=''', $pd-check, '''')" />

        
<xsl:message select="concat(' heuristic-ws-search=''', $heuristic-ws-search, '''')" />

        
<xsl:message select="'--------------------'" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''undef:param-messages'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc><xd:short><p>Checking primary data identity on the basis of primary data and textual content of XML both without whitespaces</p></xd:short></xd:doc>


    
<xsl:function name="undef:check-primary-data">

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''undef:check-primary-data'' ###')" />

        
<xsl:choose>

            
<!--checking correctness of $pd-check-->

            
<xsl:when test="not($pd-check = ('lax', 'middle', 'strict'))">

                
<xsl:message select="'*** ERROR: wrong value provided for $pd-check. Choose from: ''lax'', ''middle'' and ''strict''.'" terminate="yes" />

            
</xsl:when>

            
<xsl:when test="empty($virtual-root-node)">

                
<xsl:message select="concat('*** ERROR: no node identified by ''', $virtual-root, '''')" terminate="yes" />

            
</xsl:when>

            
<xsl:when test="exists($virtual-root-node[2])">

                
<xsl:message select="concat('*** ERROR: more than one node identified by ''', $virtual-root, '''')" terminate="yes" />

            
</xsl:when>

            
<xsl:when test="$textData_noWS != $primaryData_noWS">

                
<xsl:message select="' *** FATAL ERROR: Primary data and XML textual data mismatching!'" />

                
<xsl:message select="string-join((' *** ', string:first-distinct-char($primaryData_noWS, $textData_noWS, 1)), ' ')" terminate="yes" />

            
</xsl:when>

        
</xsl:choose>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''undef:check-primary-data'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc>

        
<xd:short><p>Insert $infiltrator (e.g. '\s*') into string (after every single char) and escape special regex chars, e.g. input: 'hello.' - output: '\s*h\s*e\s*l\s*l\s*o\s*\.\s*'</p></xd:short>

        
<xd:param name="input-string">String that is to be 'infiltrated' by another one</xd:param>

        
<xd:param name="infiltrator">String which is inserted before and after every single position of the input string</xd:param>

    
</xd:doc>


    
<xsl:function name="string:infiltrate-string" as="xs:string">

        
<xsl:param name="input-string" as="xs:string" />

        
<xsl:param name="infiltrator" as="xs:string" />

        
<xsl:variable name="input-string" select="if($infiltrator = '\s*') then replace($input-string, ' ', '') else $input-string" as="xs:string?" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''string:infiltrate-string'' ###')" />

        
<xsl:value-of select="string-join(($infiltrator, for $pos in (1 to string-length($input-string)) return (string:escape4regex(substring($input-string, $pos, 1)), $infiltrator)), '')" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''string:infiltrate-string'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc>

        
<xd:short><p>Compares two strings while ignoring whitespaces; the result is a sequence consisting of (a) the matching substring, and (b) the rest of the $pd-data which does not match</p></xd:short>

        
<xd:param name="text-node">First string to be compared to second one</xd:param>

        
<xd:param name="pd-data">Second string (to be compared to first)</xd:param>

        
<xd:param name="matching-string">Holding the respective temporary result which is enhanced by recursive call of the function</xd:param>

    
</xd:doc>


    
<xsl:function name="string:compare-strings">

        
<xsl:param name="text-node" as="xs:string" />

        
<xsl:param name="pd-data" as="xs:string" />

        
<xsl:param name="matching-string" as="xs:string" />

        
<xsl:param name="removed-leading-pd-ws" as="xs:integer" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''string:compare-strings'' ###')" />

        
<xsl:copy-of select="if(substring($pd-data, 1, 1) = substring($text-node, 1, 1)) then string:compare-strings(substring($text-node, 2), substring($pd-data, 2), concat($matching-string, substring($pd-data, 1, 1)), 0) else ( if(matches(substring($text-node, 1, 1), '\s')) then string:compare-strings(substring($text-node, 2), $pd-data, $matching-string, 0) else if(matches(substring($pd-data, 1, 1), '\s')) then string:compare-strings($text-node, substring($pd-data, 2), $matching-string, $removed-leading-pd-ws + 1) else ($matching-string, $pd-data, xs:string($removed-leading-pd-ws)) )" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''string:compare-strings'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc><xd:short><p>Deriving position information from preceding item of context item in $pd-replaced-positions</p></xd:short></xd:doc>


    
<xsl:function name="int:get-preceding-position" as="xs:integer">

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''int:get-preceding-position'' ###')" />

        
<xsl:copy-of select="(if($pd-replaced-positions[$iter - 1]) then xs:integer(string:replace-all($pd-replaced-positions[$iter - 1], ('\[', '\]'), ('', ''))) else 0)" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''int:get-preceding-position'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc>

        
<xd:short><p>Deriving first distinct char of two unequal strings </p></xd:short>

        
<xd:param name="string1">First string which shall be compared to second</xd:param>

        
<xd:param name="string2">Second string; to be compared to $string1</xd:param>

        
<xd:param name="position">Position counter for recursive calling of this funtion on substrings of the two strings</xd:param>

    
</xd:doc>


    
<xsl:function name="string:first-distinct-char" as="xs:string+">

        
<xsl:param name="string1" as="xs:string" />

        
<xsl:param name="string2" as="xs:string" />

        
<xsl:param name="position" as="xs:integer" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''string:first-distinct-char'' ###')" />

        
<xsl:choose>

            
<xsl:when test="($string1 != $string2) and ((string-length($string1) + string-length($string2)) &gt; 0)">

                
<xsl:choose>

                    
<xsl:when test="substring($string1, 1, 100) != substring($string2, 1, 100)">

                        
<xsl:variable name="string1" select="substring($string1, 1, 100)" as="xs:string" />

                        
<xsl:variable name="string2" select="substring($string2, 1, 100)" as="xs:string" />

                        
<xsl:choose>

                            
<xsl:when test="string-length($string1) = 0">

                                
<xsl:value-of select="'primary-data (', string-length($primaryData_noWS), ') is shorter than text-data (', string-length($textData_noWS), ')'" />

                            
</xsl:when>

                            
<xsl:when test="string-length($string2) = 0">

                                
<xsl:value-of select="'text-data (', string-length($textData_noWS), ') is shorter than primary-data (', string-length($primaryData_noWS), ')'" />

                            
</xsl:when>

                            
<xsl:when test="substring($string1, 1, 1) != substring($string2, 1, 1)">

                                
<xsl:value-of select="concat('Position ', $position, ': ', substring($string1, 1, 1), '!=', substring($string2, 1, 1))" />

                                
<xsl:value-of select="concat('XML: ', substring($textData_noWS, $position - 20, 21))" />

                                
<xsl:value-of select="concat('TXT: ', substring($primaryData_noWS, $position - 20, 21))" />

                            
</xsl:when>

                            
<xsl:otherwise>

                                
<xsl:value-of select="string:first-distinct-char(substring($string1, 2), substring($string2, 2), $position+1)" />

                            
</xsl:otherwise>

                        
</xsl:choose>

                    
</xsl:when>

                    
<xsl:otherwise>

                        
<xsl:value-of select="string:first-distinct-char(substring($string1, 100), substring($string2, 100), $position+100)" />

                    
</xsl:otherwise>

                
</xsl:choose>

            
</xsl:when>

            
<xsl:otherwise>

                
<xsl:value-of select="'string:first-distinct-char() examines strings with identical content!'" />

            
</xsl:otherwise>

        
</xsl:choose>

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''string:first-distinct-char'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc>

        
<xd:short><p>Function escapes certain chars of an input string by putting '\' in front </p></xd:short>

        
<xd:param name="input">String whose special 'regex' chars are to be escaped</xd:param>

    
</xd:doc>


    
<xsl:function name="string:escape4regex" as="xs:string">

        
<xsl:param name="input" as="xs:string" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''string:escape4regex'' ###')" />

        
<xsl:value-of select="replace($input, '([\.\-\*\+\$\^\?\\\(\)\(\)])', '\\$1')" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''string:escape4regex'' ###')" />

    
</xsl:function>

    

    

    
         <xd:doc>

        
<xd:short><p>Function receives message strings which are output due to $level and $ANALYZE-BUGS values</p></xd:short>

        
<xd:param name="terminate">value of @terminate of message</xd:param>

        
<xd:param name="level">The level (importance) of the bug message; if lower than $bug-message-level then message is returned</xd:param>

        
<xd:param name="message">String value of the message</xd:param>

    
</xd:doc>


    
<xsl:function name="undef:ANALYZE-BUGS">

        
<xsl:param name="terminate" as="xs:string" />

        
<xsl:param name="level" as="xs:integer" />

        
<xsl:param name="message" as="xs:string" />

        
<xsl:if test="$ANALYZE-BUGS and $level &lt;= $bug-message-level">

            
<xsl:message select="concat('*** ', $message)" terminate="{$terminate}" />

        
</xsl:if>

    
</xsl:function>

    

    

    
<xsl:function name="string:int2string" as="xs:string">

        
<xsl:param name="intSEQ" as="xs:integer+" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### START: name=''string:int2string'' ###')" />

        
<xsl:copy-of select="if($intSEQ[2]) then concat('(', string-join((for $item in $intSEQ return string($item)), ','), ')') else string($intSEQ)" />

        
<xsl:copy-of select="undef:ANALYZE-BUGS('no', 3, '### FUNC ### END: name=''string:int2string'' ###')" />

    
</xsl:function>

    

    

    
<xsl:function name="undef:iterate-non-ws" as="xs:integer">

        
<xsl:param name="string" as="xs:string?" />

        
<xsl:param name="non-ws" as="xs:string?" />

        
<xsl:param name="count" as="xs:integer" />

        
<xsl:choose>

            
<xsl:when test="$non-ws">

                
<xsl:choose>

                    
<xsl:when test="substring($string, 1, 1) = substring($non-ws, 1, 1)">

                        
<xsl:value-of select="undef:iterate-non-ws(substring($string, 2), substring($non-ws, 2), $count + 1)" />

                    
</xsl:when>

                    
<xsl:when test="matches(substring($string, 1, 1), '\s')">

                        
<xsl:value-of select="undef:iterate-non-ws(substring($string, 2), $non-ws, $count)" />

                    
</xsl:when>

                    
<xsl:otherwise>

                        
<xsl:value-of select="0" />

                    
</xsl:otherwise>

                
</xsl:choose>

            
</xsl:when>

            
<xsl:otherwise>

                
<xsl:value-of select="$count" />

            
</xsl:otherwise>

        
</xsl:choose>

    
</xsl:function>

    

    

</xsl:stylesheet>













































































v