Subject: Re: [xsl] Implementing XPointer Resolution With saxon:evaluate() From: "W. Eliot Kimber" <eliot@xxxxxxxxxx> Date: Wed, 14 Aug 2002 09:59:54 -0500 |
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><</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>></xsl:text> <xsl:apply-templates mode="echo-markup"/> <xsl:text><</xsl:text><xsl:value-of select="name()"/><xsl:text>></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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Implementing XPointer Res, Jeni Tennison | Thread | Re: [xsl] Implementing XPointer Res, Jeni Tennison |
Re: [xsl] Implementing XPointer Res, Jeni Tennison | Date | Re: [xsl] Implementing XPointer Res, W. Eliot Kimber |
Month |