xsl-list
[Top] [All Lists]

Re: FW: Stopping recursion

2005-11-22 04:33:00
From: Michael Kay <mike(_at_)saxonica(_dot_)com>
Reply-To: <xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com>
Date: Tue, 22 Nov 2005 11:21:07 -0000
To: <xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com>
Subject: RE: [xsl] FW: Stopping recursion

There are a few problems with this stylesheet - for example I don't think it
handles a no-namespace schema, or model groups, or types derived by
extension, or perhaps quite a few other things. I'm also not sure whether
the test test=".//@namespace='http://www.w3.org/1999/xlink'" is doing the
right thing: this seems designed to catch element and attribute wildcards,
but I would have thought you also wanted to catch XLink attributes declared
explicitly.

True, though to be fair the stylesheet only has to work with the subset of
WXS that I know we are using, so I have taken shortcuts.
 
However, to stick to the question you are asking: I think you need to
separate the functionality into two parts: a template that determines
whether an element directly-or-indirectly allows XLink attributes, and a
template that adds an xml:base attribute. The logic should be "if this
element declaration directly-or-indirectly allows XLink attributes, then add
an xml:base attribute", where the logic for testing each element declaration
returns a yes/no result but does not produce a modified element declaration
as output.

This logic will visit the same element many times, which of course has
performance implications. An easy but non-standard answer to that is Saxon
memo functions. A more portable answer is to pass parameters on your
recursive calls indicating the elements already visited: perhaps two lists,
one for those known to allow XLink attributes, another for those known not
to.

Thanks very much, most useful.

All the best

Mark
 
Michael Kay
http://www.saxonica.com/


-----Original Message-----
From: Mark Seaborne [mailto:mseaborne(_at_)origoservices(_dot_)com]
Sent: 22 November 2005 11:00
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] FW: Stopping recursion

Hi,

I have a 1.0 stylesheet that takes a WXS schema and adds
xml:base to certain
complex type definitions. The rule for inclusion of the
attribute is that
the complex type must either include directly, or have a descendent in
another complex type that includes the XLink namespace.

So the stylesheet recurses through each complex type and
tests to see if
they contain anything belonging to the XLink namespace. If the type is
itself a complex type the template is called again to check
to see if that
one has any elements within the XLink namespace, and so on.
If the XLink
namespace is found then <xsd:attribute ref="xml:base"/> is output.

My problem is that once the XLink namespace is found I would like the
recursion to stop, mainly because if the namespace is found
in more than one
descendent element/attribute declaration the attribute is
added multiple
times. 

I suspect that either my approach is totally wrong, or this
is a common
enough problem that there is a design pattern I can use to achieve the
effect I want, but I haven't hit on the key words to find it. So any
pointers would be gratefully received.

This is the template causing the problem:

<xsl:template match="xsd:element" mode="findXLink">
   <xsl:choose>
   <!-- if the element is declared locally (has a type attribute_ -->
      <xsl:when test="@type">
        <!-- remove the namespace prefix from the qname -->
        <xsl:variable name="myType"
select="substring-after(@type, ':')"/>
        <xsl:for-each
select="/xsd:schema/xsd:complexType[(_at_)name = $myType]">
        <xsl:choose>
        <!-- if the complex type definition includes anything
in the XLink
namespace output the xml:base attribute -->
          <xsl:when
test=".//@namespace='http://www.w3.org/1999/xlink'">
            <xsd:attribute ref="xml:base"/>
          </xsl:when>
       <!-- otherwise apply this template to all of the
elements declared
within the complex type -->
          <xsl:otherwise>
             <xsl:apply-templates select=".//xsd:element"
mode="findXLink"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </xsl:when>
    <!-- otherwise assume that the element references a
globally declared
element, so look for that -->
    <xsl:otherwise>
      <xsl:variable name="myName"
select="substring-after(@ref, ':')"/>
      <xsl:apply-templates select="//xsd:element[(_at_)name = $myName]"
mode="findXLink"/>
     </xsl:otherwise>
   </xsl:choose>
</xsl:template>

All the best

Mark
The information in this e-mail is sent in confidence for the
addressee only and may be legally privileged. Unauthorised
recipients must preserve this confidentiality and should
please advise the sender immediately of the error in
transmission and then delete this e-mail. If you are not the
intended recipient, any disclosure, copying, distribution or
any action taken in reliance on its content is prohibited and
may be unlawful.

Origo Services Limited accepts no responsibility for any loss
or damage resulting directly or indirectly from the use of
this e-mail or the contents.  It is your responsibility to
scan for viruses.  Origo Services Limited reserves the right
to monitor e-mails sent to or from addresses under its
control.  When you reply to this e-mail, you are consenting
to Origo Services Limited monitoring the content of the
e-mails you send to or receive from Origo Services Limited.
If this e-mail is non-business related Origo Services Limited
is not liable for any opinions expressed by the sender.  The
contents of this e-mail are protected by copyright.  All
rights reserved.



Origo Services Limited is a company incorporated in Scotland
(company number 115061) having its registered office at 4th
floor, Saltire Court, 20 Castle Terrace, Edinburgh EH1 2EN.

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--





--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

The information in this e-mail is sent in confidence for the addressee only and 
may be legally privileged. Unauthorised recipients must preserve this 
confidentiality and should please advise the sender immediately of the error in 
transmission and then delete this e-mail. If you are not the intended 
recipient, any disclosure, copying, distribution or any action taken in 
reliance on its content is prohibited and may be unlawful.

Origo Services Limited accepts no responsibility for any loss or damage 
resulting directly or indirectly from the use of this e-mail or the contents.  
It is your responsibility to scan for viruses.  Origo Services Limited reserves 
the right to monitor e-mails sent to or from addresses under its control.  When 
you reply to this e-mail, you are consenting to Origo Services Limited 
monitoring the content of the e-mails you send to or receive from Origo 
Services Limited.  If this e-mail is non-business related Origo Services 
Limited is not liable for any opinions expressed by the sender.  The contents 
of this e-mail are protected by copyright.  All rights reserved.



Origo Services Limited is a company incorporated in Scotland (company number 
115061) having its registered office at 4th floor, Saltire Court, 20 Castle 
Terrace, Edinburgh EH1 2EN.

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>