This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: document() and fragment


Thank you all for your replies. The reason I was using this feature was 
because I have documents that are inter-linked using XLinks, with each 
XLink pointing to a specific element in the document via a bare name 
XPointer.

I can see how the Saxon behavior is oriented to do embedded stylesheets. 
When I was poking around with the source code I noticed that if you have 
multiple links to the same document (e.g. "doc.xml#id1", "doc.xml#id2") 
the document gets parsed multiple times, each time with a different SAX 
filter. So, I imagine the Saxon behavior is not really suitable 
performance-wise when you have a lot of links between a small number of 
documents (such as what I have). Also, I don't know how the Saxon 
behavior works with things like generate-id() or not because I didn't 
test it that much.

I have written an extension function with the EXSLT functions module 
that will do fragment id's (bare name XPointers). It is included below. 
Please note that it is pretty limited because I just had a short time to 
work on it. When I have more time I will extend it work more like the 
XSLT document() function w.r.t. the first parameter being a node-set. 
Also, I will try to make it be a complete XPointer implementation if 
that is possible using the EXSLT evaluate() function. If you find a bug 
please let me know.

Thanks,
Brian

<?xml version='1.0'?>
<!-- XLink Support v 0.1 by Brian L. Smith (brian-l-smith@uiowa.edu).
      Limitations:
       1. If the first parameter is a node-set, only the first node
          in the node-set is used. In the future, this function will
          treat the first parameter exactly the same way that document()
          treats its first parameter.

      I baven't tested this very much. If you find a bug please let me
      know.

      Misc: The behavior of bls:xlink(string) is slightly different than
            the XSL document(string) function. The XSL document(string)
            function will use the base URI that is active in the
            stylesheet instead of the base URI that is in effect for the
            source document. The bls:xlink(string) function does just the
            opposite: it will use the base URI that is in effect for the
            current document node instead of the base URI in effect in
            the stylesheet. The reason for the difference is that I don't
            know how to get the base URI that is in effect for the
            importing stylesheet in (E)XSLT.
   -->
<xsl:stylesheet version='1.0'
    xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
    xmlns:exslt='http://exslt.org/common'
    xmlns:func='http://exslt.org/functions'
    xmlns:bls='http://www.brianlsmith.org/XSL'
 >

<func:function name='bls:href'>
   <xsl:param name='href'/>
   <xsl:param name='base' select='bls:get-base-node($href)'/>

   <xsl:for-each
     select='document(substring-before(concat($href, "#"), "#"), $base)'>
     <func:result select=' current()[not(contains($href, "#"))]
                         | id(substring-after($href, "#"))'/>
   </xsl:for-each>
</func:function>

<func:function name='bls:get-base-node'>
   <xsl:param name='nodeset-or-string'/>
   <xsl:choose>
     <xsl:when test='exslt:object-type($nodeset-or-string) = "node-set"'>
       <func:result select='$nodeset-or-string'/>
     </xsl:when>
     <xsl:otherwise>
       <func:result select='.'/>
     </xsl:otherwise>
   </xsl:choose>
</func:function>

</xsl:stylesheet>



Michael Kay wrote:

> Looking again at the spec, you're probably correct that
> document("doc.xml#text") should build a tree representing the entire
> document, and then return a reference to the element with ID "text", rather
> than building a tree rooted at the "text" element. The current design is
> essentially a side-effect of the way that Saxon implements embedded
> stylesheets, and is handy because it saves memory when you only want access
> to a small part of a secondary input document. For the effect that you want,
> I'd suggest you avoid using the fragment identifier (they aren't very
> portable anyway), and instead use the id() function to select the nodes you
> want within the retrieved document.
> 
> Mike Kay
> 
> 
>>-----Original Message-----
>>From: owner-xsl-list@lists.mulberrytech.com
>>[mailto:owner-xsl-list@lists.mulberrytech.com]On Behalf Of Brian Smith
>>Sent: 17 December 2001 05:48
>>To: XSL-List@lists.mulberrytech.com
>>Subject: [xsl] document() and fragment
>>
>>
>>Saxon 6.4.4 supports using a fragment identifier (bare name xpointer)
>>with the document function like this:
>>document("doc.xml#text"). This is
>>very handy but it is causing me a problem with the way the resulting
>>node-set is rooted.
>>
>>Lets say I have this document, doc.xml (assume "id" is an ID
>>attribute):
>>
>>  <root>
>>    <package id="a1" name="javax">
>>        <package id="a2" name="swing">
>>           <package id="a3" name="text"/>
>>        </package>
>>    </package>
>>  </root>
>>
>>Now, lets say I'm processing another document, and I evaluate the
>>expression document("doc.xml#a3"). Saxon will return a
>>node-set with a
>>root node containing the package element with id "a3"
>>("text"). But, I
>>need to traverse the ancestor:: axis in order to get the
>>fully-qualified
>>  name of the package ("javax.swing.text"), such as by doing this:
>>
>><xsl:for-each select='document("doc.xml#text")/*
>>                                       /ancestor-or-self::package'>
>>      <xsl:value-of select='@name'/>
>>      <xsl:if test='position() != last()'>.</xsl:if>
>></xsl:for-each>
>>
>>Unfortunately, this doesn't work because the result of
>>"document()" will
>>be rooted at the "a3" node, not at the actual root of the doucment.
>>
>>Is there any way around this? I wish the document() function
>>behaved in
>>a way that would allow me to access the ancestors and predecessors of
>>the selected element.
>>
>>Thanks,
>>Brian
>>
>>
>> XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
>>
>>
> 
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 



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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]