tags:

views:

371

answers:

2

I would like to transform any http/s based url inside random text to be automatically tagged with xsl-fo , where the random text might contains one or more http/s based url.

So the http/s url is not part of an attribute or the only content of a node, but part of text within a node.

For example: the source

<misc>
  <comment>Yada..yada..yadda, see http://www.abc.com. 
           Bla..bla..bla.. http://www.xyz.com&lt;/comment&gt;
</misc>

Will be transform into something like:

<fo:block>
  Yada..yada..yadda, see <fo:basic-link external-destination="http://www.abc.com"&gt;http://www.abc.com&lt;/fo:basic-link&gt;.
  Bla..bla..bla.. <fo:basic-link external-destination="http://www.xyz.com"&gt;http://www.xyz.com&lt;/fo:basic-link&gt;
<fo:/block>

The library we are using is Apache FOP and Xalan-J.

A: 

I don't know what xsl:fo means, but if you have access to the xslt file that actually does the conversion, you might convert it yourself by using xml string functions mentioned here. If you have access to the transformed output only, you still can

  • apply another xslt that does what you want or
  • transform it yourself using SAX and using the java regex functions
dhiller
+2  A: 

If you have to use a pure XSLT method, you could use this:

<xsl:template match="comment">
  <fo:block>
    <xsl:call-template name="dig-links">
      <xsl:with-param name="content" select="."/>
    </xsl:call-template>
  </fo:block>
</xsl:template>
<xsl:template name="dig-links">
  <xsl:param name="content" />
  <xsl:choose>
    <xsl:when test="contains($content, 'http://')"&gt;
      <xsl:value-of select="substring-before($content, 'http://')"/&gt;
      <xsl:variable name="url" select="concat('http://', substring-before(substring-after(concat($content, ' '), 'http://'), ' '))"/>
      <fo:basic-link>
        <xsl:attribute name="external-destination">
          <xsl:choose>
            <xsl:when test="substring($url, string-length($url), 1) = '.'">
              <xsl:value-of select="substring($url, 1, string-length($url)-1)"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="$url"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
        <xsl:value-of select="$url"/>
      </fo:basic-link>
      <xsl:call-template name="dig-links">
        <xsl:with-param name="content" select="substring-after($content, $url)"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$content"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

It's not a perfect solution however, thus if you have typos such as two dots at the end of a url, the external-destination attribute will get one.

Erlock