Search code examples
xmlxsltxslt-2.0

Link is coming for whole text


Hi I'm having the below input xml file:

<Description>See <XRef href="push">Time</XRef>, <XRef href="back">Late</XRef>,  <XRef href="some">Come</XRef></Description>

XSL I have tried for the above code:

<xsl:template match="Description">
        <def>
            <para>
                <xsl:value-of select="normalize-space(node()[1])"/>
                <xsl:if test="XRef">
                    <xsl:choose>
                        <xsl:when test="TEST">
                            <xref>
                                <xsl:attribute name="endterm">

                                </xsl:attribute>
                                <xsl:attribute name="linkend">

                                </xsl:attribute>
                            </xref>
                        </xsl:when>
                        <xsl:otherwise>
                            <link>
                                <xsl:choose>
                                    <xsl:when test="@destination='yes'">
                                        <xsl:attribute name="xlink:href">
                                            <xsl:text>test.pdf</xsl:text>
                                        </xsl:attribute> 
                                    </xsl:when>
                                    <xsl:otherwise>
                                        <xsl:attribute name="mark">

                                        </xsl:attribute> 
                                    </xsl:otherwise>
                                </xsl:choose>
                                <xsl:value-of select="."/>       
                            </link>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:if>
                </para>
        </def>
    </xsl:template>

Getting Output like this:

<def>
   <para>See<link mark="">See Time, Late, Come</link></para>
</def>

Expected output be like:

<def>
    <para>See <link mark="">Time</link>, <link mark="">Late</link>, <link mark="">Come</link></para>
</def>

I'm getting the link for whole xref, But I need it individual. Please suggest a code for this.


Solution

  • You should consider changing your approach to use templates, as you may find it is much cleaner and easier to adapt.

    So, to change the Description element into def and para, do this

    <xsl:template match="Description">
      <def>
        <para>
          <xsl:apply-templates />
        </para>
      </def>
    </xsl:template>
    

    For XRef you seem to have some logic depending on whether a TEST element is present or not. You can handle this with two separate templates

    <xsl:template match="XRef[TEST]">
      <xref endterm="" linkend="" />
    </xsl:template>
    
    <xsl:template match="XRef">
      <link>
        <xsl:choose>
          <xsl:when test="@destination='yes'">
            <xsl:attribute name="xlink:href">test.pdf</xsl:attribute> 
          </xsl:when>
          <xsl:otherwise>
            <xsl:attribute name="mark" />
          </xsl:otherwise>
        </xsl:choose>
        <xsl:value-of select="."/>       
      </link>
    </xsl:template>
    

    You could, of course, extend this logic quite easily with other cases.

    Try this XSLT

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xlink="..."
        exclude-result-prefixes="#all"
        version="1.0">
    
      <xsl:output method="xml" indent="yes" />
    
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="Description">
        <def>
          <para>
            <xsl:apply-templates />
          </para>
        </def>
      </xsl:template>
    
      <xsl:template match="XRef[TEST]">
        <xref endterm="" linkend="" />
      </xsl:template>
    
      <xsl:template match="XRef">
        <link>
          <xsl:choose>
            <xsl:when test="@destination='yes'">
              <xsl:attribute name="xlink:href">test.pdf</xsl:attribute> 
            </xsl:when>
            <xsl:otherwise>
              <xsl:attribute name="mark" />
            </xsl:otherwise>
          </xsl:choose>
          <xsl:value-of select="."/>       
        </link>
      </xsl:template>
    </xsl:stylesheet>
    

    Note the first template is the "identity template" which would be used to copy all other nodes in your document unchanged (although it is not needed for the specific XML sample in your question).

    See it in action at http://xsltfiddle.liberty-development.net/6rewNxF