[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Implementing XPointer Resolution With saxon:evalua

Subject: Re: Implementing XPointer Resolution With saxon:evaluate()
From: "W. Eliot Kimber" <eliot@xxxxxxxxxx>
Date: Wed, 14 Aug 2002 09:59:54 -0500
saxon xlink
Ok, I seem to have everything working, at least within the scope of a
single document (I haven't stepped up to handling cross-document
XPointers, although I know how to do it).

Here are the parts of my initial solution (tested with Saxon, but should
work with any XSLT processor that implements the EXSLT common and
function packages):

1. Indirector functions (implemented using EXSLT function features and
XSLT as the implementation language) (xindirect-functions.xsl):

<?xml version='1.0'?>
<!-- Copyright (c) 2002 ISOGEN International -->
<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xlink="http://www.w3.org/TR/xlink"
  xmlns:xindr="http://www.isogen.com/papers/xindirection.xml"
  xmlns:xindrf="http://www.isogen.com/functions/xindirection"
  xmlns:saxon="http://icl.com/saxon"
  xmlns:func="http://exslt.org/functions"
  xmlns:fcommon="http://exslt.org/common"
  extension-element-prefixes="func xindrf"
>

<func:function name="xindrf:resolve-indirector">
  <xsl:param name="indirector-node"/>
  <xsl:variable name="indirector-treatment-str"
select="string(@indirector-treatment)"/>
  <func:result select="xindrf:resolve-xpointer($indirector-node,
$indirector-treatment-str)"/>
</func:function>

<func:function name="xindrf:resolve-xpointer">
  <xsl:param name="pointer-node"/><!-- The Element node that exhibits
the XPointer to be resolved -->
  <xsl:param name="indirector-treatment">as-indirector</xsl:param>
  <xsl:variable name="indirector-treatment-str"
select="string($indirector-treatment)"/>
  <xsl:variable name="xpointer">
    <xsl:choose>
      <xsl:when test="starts-with($pointer-node/@href,'#')">
        <xsl:value-of select="substring($pointer-node/@href, 2)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$pointer-node/@href"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="$xpointer != ''">     
      <xsl:variable name="direct-result-set"
select="saxon:evaluate($xpointer)"/>
      <xsl:for-each select="$direct-result-set">
        <xsl:choose>
          <xsl:when test="self::xindr:indirector and
($indirector-treatment-str != 'as-resource')" >
            <func:result select="xindrf:resolve-indirector(.)"/>
          </xsl:when>
          <xsl:otherwise>
            <func:result select="."/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </xsl:when>
    <xsl:otherwise>
      <xsl:message>
*** XIndirect error: $xpointer value is '' in resolve-xpointer.
      </xsl:message>
    </xsl:otherwise>
  </xsl:choose>  
</func:function>
</xsl:stylesheet>

2. Processing test script:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xlink="http://www.w3.org/TR/xlink"
  xmlns:xindr="http://www.isogen.com/papers/xindirection.xml"
  xmlns:xindrf="http://www.isogen.com/functions/xindirection"
  xmlns:saxon="http://icl.com/saxon"
  xmlns:func="http://exslt.org/functions"
  xmlns:fcommon="http://exslt.org/common"
  extension-element-prefixes="func xindrf"
>

<xsl:import href="./xindirect-functions.xsl"/>

<xsl:output 
  method="xml" 
  indent="no"
  omit-xml-declaration="no" 
  encoding="UTF-8"
/>

<xsl:template match="/">
  <html>
    <body>
      <div>
      <hr/>
      <h2>Input Document</h2>
      <pre>
      <xsl:apply-templates mode="echo-markup"/>
      </pre>
      </div>
      <div>
      <hr/>
      <h2>Debug Report</h2>
      <xsl:apply-templates/>
      </div>
    </body>
  </html>
</xsl:template>

<xsl:template match="links">
  <div>
    <h2>Links</h2>
    <table border="1" width="100%">
      <xsl:apply-templates/>
    </table>
  </div>
</xsl:template>

<xsl:template match="xlink:simple">
  <!-- <xsl:message>*** Starting xlink:simple</xsl:message> -->
  <tr>
    <td><a name="{generate-id()}"
      /><xsl:text>[</xsl:text
      ><xsl:value-of select="generate-id()"
      /><xsl:text>] Initial pointer: </xsl:text>
      <xsl:value-of select="@href"/><xsl:text>: </xsl:text>
      <xsl:apply-templates/>
      <br/><xsl:text>Direct targets: </xsl:text>
      <xsl:apply-templates 
          select="xindrf:resolve-xpointer(., 'as-resource')" 
          mode="generate-link-to"/>
    </td>
    <td>
      <xsl:text>ID of ultimate target: </xsl:text>
      <xsl:variable name="members" select="xindrf:resolve-xpointer(.)"/>
      <!-- <xsl:message>$members='<xsl:copy-of
select="$members"/>'</xsl:message> -->
      <xsl:for-each select="$members">
        <!-- <xsl:message>member[<xsl:value-of
select="position()"/>]=<xsl:copy-of select="."/></xsl:message> -->
        <br/>
        <a href="#{generate-id()}"
        ><xsl:value-of select="generate-id()"
        /></a>: <code><xsl:apply-templates select="."
mode="echo-markup"/></code>
      </xsl:for-each>
    </td>
  </tr>
</xsl:template>

<xsl:template match="paras">
  <div>
    <h2>Paragraphs</h2>
    <xsl:apply-templates/>
  </div>
</xsl:template>

<xsl:template match="para">
  <p
    ><a name="{generate-id()}"
    /><xsl:text>[</xsl:text
    ><xsl:value-of select="generate-id()"
    /><xsl:text
    >]</xsl:text
  ><xsl:apply-templates
  /></p>
</xsl:template>

<xsl:template match="xindr:indirectorset">
  <div>
    <h2>Indirectors</h2>
    <table border="1" width="100%">
      <xsl:apply-templates/>
    </table>
  </div>
</xsl:template>

<xsl:template match="xindr:indirector">
  <xsl:variable name="direct-target" select="xindrf:resolve-xpointer(.,
'as-resource')"/>
  <tr>
    <td><a name="{generate-id()}"
      /><xsl:text>[</xsl:text
      ><xsl:value-of select="generate-id()"
      /><xsl:text>] Pointer: </xsl:text
      ><xsl:value-of select="@href"/>
    </td>
    <td>
      <xsl:text>Direct targets: </xsl:text
      >
      <xsl:apply-templates select="$direct-target"
mode="generate-link-to"/>
    </td>
  </tr>  
</xsl:template>

<xsl:template match="*" mode="generate-link-to">
    <br/>
    <a href="#{generate-id()}"
    ><xsl:value-of select="generate-id()"
    /></a>: <code><xsl:apply-templates select="."
mode="echo-markup"/></code>
</xsl:template>

<xsl:template name="echo-element-markup">
  <xsl:text>&lt;</xsl:text><xsl:value-of select="name()"/>
  <xsl:for-each select="./attribute::*">
    <xsl:text>  </xsl:text><xsl:value-of select="name()"/>=<xsl:value-of
select="."/>
  </xsl:for-each>
  <xsl:text>&gt;</xsl:text>
  <xsl:apply-templates mode="echo-markup"/>
  <xsl:text>&lt;</xsl:text><xsl:value-of
select="name()"/><xsl:text>&gt;</xsl:text>  
</xsl:template>

<xsl:template match="*" mode="echo-markup">
  <xsl:call-template name="echo-element-markup"/>
</xsl:template>
</xsl:stylesheet> 

3. Sample input document:

<?xml version="1.0"?>
<xindrtest 
  xmlns:xindr="http://www.isogen.com/papers/xindirection.xml"
  xmlns:xlink="http://www.w3.org/TR/xlink"
>
<links>
<xlink:simple href="#//*[@id='addr-01']">indirect link to para
1</xlink:simple>
<xlink:simple href="#//*[@id='addr-02']">indirect link to para
2</xlink:simple>
<xlink:simple href="#//*[@id='addr-03']">double indirect link to para
2</xlink:simple>
</links>
<paras>
<para>This is the first para</para>
<para>This is the second para</para>
</paras>
<xindr:indirectorset>
<xindr:indirector id="addr-01"
  href="#/*/paras/para[1]">pointer to para 1</xindr:indirector>
<xindr:indirector id="addr-02"
  href="#/*/paras/para[2]">pointer to para 2</xindr:indirector>
<xindr:indirector id="addr-03"
  href="#../xindr:indirector[2]">pointer to indirector
"addr-02"</xindr:indirector>
</xindr:indirectorset>
</xindrtest>

-- 
W. Eliot Kimber, eliot@xxxxxxxxxx
Consultant, ISOGEN International

1016 La Posada Dr., Suite 240
Austin, TX  78752 Phone: 512.656.4139

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.