Subject: RE: [xsl] FW: Stopping recursion From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Tue, 22 Nov 2005 11:21:07 -0000 |
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. 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. Michael Kay http://www.saxonica.com/ > -----Original Message----- > From: Mark Seaborne [mailto:mseaborne@xxxxxxxxxxxxxxxxx] > Sent: 22 November 2005 11:00 > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > 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[@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[@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.
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] FW: Stopping recursion, Mark Seaborne | Thread | Re: [xsl] FW: Stopping recursion, David Carlisle |
[xsl] FW: Stopping recursion, Mark Seaborne | Date | Re: [xsl] FW: Stopping recursion, David Carlisle |
Month |