Lexical relations from left to right

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="2.0">

   <xsl:output method="xml" version="1.0" encoding="utf-8" 
        omit-xml-declaration="yes" indent="yes"/>
<!-- Root element match feature structure -->
   <xsl:template match="/fs">
<!-- xsl:element name="relations" -->
       <xsl:apply-templates/>
<!-- /xsl:element -->
   </xsl:template>

<!-- we see a feature, we look at the value -->
 <xsl:template match="f">
    <xsl:variable name="sourceid">
       <xsl:value-of select="@name/generate-id()"/>
    </xsl:variable>
<!-- only the features that do not refer to other features -->
    <xsl:for-each select=".[not(@fVal)]">

<!-- Now let's look at the features which 
     have embedded features -->
<!-- first without reentrancy -->
      <xsl:for-each select="fs/f[not(@fVal)]">
         <xsl:element name="relation">
            <xsl:attribute name="type">
               <xsl:text>is_instanced_by</xsl:text>
            </xsl:attribute>
            <xsl:element name="source">
               <xsl:attribute name="idref">
                <xsl:value-of 
                 select="../../@name/generate-id()"/>
               </xsl:attribute>
            </xsl:element>
            <xsl:element name="target">
               <xsl:attribute name="idref">
                 <xsl:value-of select="@name/generate-id()"/>
               </xsl:attribute>
            </xsl:element>
         </xsl:element>
      </xsl:for-each>

<!-- Well, now we have to look at the features with 
     reentrancy -->
         <xsl:for-each select="fs/f[@fVal]">
            <xsl:variable name="fVal">
               <xsl:value-of select="@fVal"/>
            </xsl:variable>
            <xsl:for-each select="//fs[@id=$fVal]/f">
              <xsl:element name="relation">
                <xsl:attribute name="type">
                  <xsl:text>is_instanced_by</xsl:text>
                </xsl:attribute>
                <xsl:element name="source">
                  <xsl:attribute name="idref">
                     <xsl:value-of select="$sourceid"/>
                  </xsl:attribute>
                </xsl:element>

                <xsl:element name="target">
                  <xsl:attribute name="idref">
                    <xsl:value-of select="@name/generate-id()"/>
                  </xsl:attribute>
                </xsl:element>
              </xsl:element>
            </xsl:for-each>
         </xsl:for-each>
         <xsl:for-each select=".[not(fs)]">
            <xsl:element name="relation">
              <xsl:attribute name="type">
                <xsl:text>has_instance</xsl:text>
              </xsl:attribute>
              <xsl:element name="source">
                <xsl:attribute name="idref">
                  <xsl:value-of select="@name/generate-id()"/>
                </xsl:attribute>
              </xsl:element>
              <xsl:element name="target">
                <xsl:attribute name="idref">
                  <xsl:if test="str">
                    <xsl:value-of select="str/generate-id()"/>
                  </xsl:if>
                  <xsl:if test="plus">
                    <xsl:value-of select="plus/generate-id()"/>
                  </xsl:if>
                </xsl:attribute>
              </xsl:element>
            </xsl:element>
         </xsl:for-each>
      </xsl:for-each>

      <xsl:apply-templates/>

   </xsl:template>

   <xsl:template match="fs">
      <xsl:apply-templates/>
   </xsl:template>


<!-- Here we have the terminal symbols str and plus 
 we can deal with them easily by referring to them and 
looking at the feature -->
   <xsl:template match="str">
   </xsl:template>

   <xsl:template match="plus">
   </xsl:template>


</xsl:stylesheet>
Thorsten Trippel 2006-11-18