Subject: RE: [xsl] selecting everything below a node From: Jorg Heymans <Jorg.Heymans@xxxxxxxxxx> Date: Thu, 7 Aug 2003 11:45:40 +0100 |
Answering to my own question ... :-) There was a namespace on the aggregated request document. So instead of referencing /aggregate/request/etc I did /aggregate/req:request. I didn't see the namespaces at first because mozilla leaves them out in the browser. it works perfectly now! Thanks again Markus. -----Original Message----- From: Jorg Heymans [mailto:Jorg.Heymans@xxxxxxxxxx] Sent: Donnerstag, 7. August 2003 12:00 To: 'xsl-list@xxxxxxxxxxxxxxxxxxxxxx' Subject: RE: [xsl] selecting everything below a node Hi Markus, Thanks for this solution! I have applied your tips, but in the replace-one-param function it never gets passed condition <!-- Terminate if no more parameters there --> <xsl:when test="not(/aggregate/request/parameter[$replace-param])"> <xsl:value-of select="$input"/> </xsl:when> Even though the xml has several parameter elements under /aggregate/request. Is it even possible to still access the original root document, even though my first template goes like <xsl:template match="/" > <xsl:apply-templates select="aggregate/content"/> </xsl:template> Could this be the problem? Here is the full template now xsl:template match="/" > <xsl:apply-templates select="aggregate/content"/> </xsl:template> <xsl:template match="node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- match all attribute values --> <xsl:template match="@*"> <xsl:attribute name="{name()}"> <xsl:call-template name="replace-one-param"> <xsl:with-param name="input" select="."/> <xsl:with-param name="replace-param" select="1"/> </xsl:call-template> </xsl:attribute> </xsl:template> <xsl:template name="replace-one-param"> <xsl:param name="input"/> <xsl:param name="replace-param"/> <xsl:choose> <!-- Terminate if no more parameters there , this seems always true somehow --> <xsl:when test="not(/aggregate/request/parameter[$replace-param])"> <xsl:comment><xsl:value-of select="/aggregate/request/ parameter[$replace-param]"/></xsl:comment> <xsl:value-of select="$input"/> </xsl:when> <xsl:otherwise> <!-- Replace all occurances of one parameter and store the result in $tempresult --> <xsl:variable name="tempresult"> <xsl:call-template name="substring-replace"> <xsl:with-param name="search-for" select="/aggregate/request/parameter[$replace-param]/@name"/> <xsl:with-param name="replace-with" select="/aggregate/request/parameter[$replace-param]/value"/> <xsl:with-param name="input" select="$input"/> </xsl:call-template> </xsl:variable> <!-- Replace the next parameter --> <xsl:call-template name="replace-one-param"> <xsl:with-param name="input" select="$tempresult"/> <xsl:with-param name="replace-param" select="$replace-param+1"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="substring-replace"> <xsl:param name="input"/> <xsl:param name="search-for"/> <xsl:param name="replace-with"/> <xsl:message>substring search is :<xsl:value-of select="$input"/><xsl:value-of select="$search-for"/><xsl:value-of select="$replace-with"/></xsl:message> <xsl:choose> <!-- empty search string produces infinite loop --> <xsl:when test="$search-for=''"> <xsl:value-of select="$input"/> </xsl:when> <xsl:when test="contains($input, $search-for)"> <xsl:value-of select="substring-before($input, $search-for)"/> <xsl:value-of select="$replace-with"/> <xsl:call-template name="substring-replace"> <xsl:with-param name="input" select="substring-after($input,$search-for)"/> <xsl:with-param name="search-for" select="$search-for"/> <xsl:with-param name="replace-with" select="$replace-with"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$input"/> </xsl:otherwise> </xsl:choose> </xsl:template> -----Original Message----- From: Markus Abt [mailto:abt@xxxxxxxx] Sent: Mittwoch, 6. August 2003 20:03 To: 'xsl-list@xxxxxxxxxxxxxxxxxxxxxx' Subject: AW: [xsl] selecting everything below a node Hi Jorg, five steps towards the goal: (1) Your pattern "aggregate/content//@*" matches two templates. You want only the second matching template to match, so remove this pattern from the first template: <xsl:template match="node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> (2) You cannot output a comment node directly followed by an attribute node. Either reverse the order, or use <xsl:message> instead of <xsl:comment> for debugging: <!-- match all attribute values --> <xsl:template match="aggregate/content//@*"> <xsl:message><xsl:value-of select="."/></xsl:message> <xsl:attribute name="{name()}"> [...] (3) You cannot put a comment node into an attribute node. Use <xsl:message> instead of <xsl:comment> for debugging: <xsl:template name="substring-replace"> <xsl:param name="input"/> <xsl:param name="search-for"/> <xsl:param name="replace-with"/> <xsl:message><xsl:value-of select="$input"/><xsl:value-of select="$search-for"/><xsl:value-of select="$replace-with"/></xsl:message> <xsl:choose> [...] (4) In you recursive call to the substring-replace template, you have to set the values for the search-for and replace-with parameters. In your last template, write: <xsl:when test="contains($input, $search-for)"> <xsl:value-of select="substring-before($input, $search-for)"/> <xsl:value-of select="$replace-with"/> <xsl:call-template name="substring-replace"> <xsl:with-param name="search-for" select="$search-for"/> <xsl:with-param name="replace-with" select="$replace-with"/> <xsl:with-param name="input" select="substring-after($input,$search-for)"/> </xsl:call-template> </xsl:when> (5) You can loop with another recursive called template to replace one parameter by the other: <!-- match all attribute values --> <xsl:template match="aggregate/content//@*"> <xsl:message><xsl:value-of select="."/></xsl:message> <xsl:attribute name="{name()}"> <xsl:call-template name="replace-one-param"> <xsl:with-param name="input" select="."/> <xsl:with-param name="replace-param" select="1"/> </xsl:call-template> </xsl:attribute> </xsl:template> <xsl:template name="replace-one-param"> <xsl:param name="input"/> <xsl:param name="replace-param"/> <xsl:choose> <!-- Terminate if no more parameters there --> <xsl:when test="not(/aggregate/request/parameter[$replace-param])"> <xsl:value-of select="$input"/> </xsl:when> <xsl:otherwise> <!-- Replace all occurances of one parameter and store the result in $tempresult --> <xsl:variable name="tempresult"> <xsl:call-template name="substring-replace"> <xsl:with-param name="search-for" select="/aggregate/request/parameter[$replace-param]/@name"/> <xsl:with-param name="replace-with" select="/aggregate/request/parameter[$replace-param]"/> <xsl:with-param name="input" select="$input"/> </xsl:call-template> </xsl:variable> <!-- Replace the next parameter --> <xsl:call-template name="replace-one-param"> <xsl:with-param name="input" select="$tempresult"/> <xsl:with-param name="replace-param" select="$replace-param+1"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> Putting this all together should make it. Note, that there are some special cases I did not resolve here. For example, if one placeholder contains an other placeholder, then this is replaced if, and only if, the containing placeholder comes before the contained placeholder in the parameter list. Regards, Markus __________________________ Markus Abt Comet Computer GmbH http://www.comet.de ---------- Von: Jorg Heymans Gesendet: Mittwoch, 6. August 2003 18:05 An: 'xsl-list@xxxxxxxxxxxxxxxxxxxxxx' Betreff: RE: [xsl] selecting everything below a node Hi Markus, Actually I do want to modify parts. Given following (a bit more complete now) xml <aggregate> <request> <parameter name="placeholder1">textvalue</parameter> <parameter name="placeholder2">anothertextvalue</parameter> </request> <content> <url src="http://myurl?text=placeholder1"/> <url src=http://myurl?text=placeholder2"/> </content> </aggregate> I would like to - extract the content tree - for each of the parameter name attributes in the request tree I want to search the content tree and replace all occurrences of this parameter name attribute with the parameter value attribute I think I'm close to the solution though <xsl:template match="/" > <xsl:apply-templates select="aggregate/content"/> </xsl:template> <xsl:template match="aggregate/content//@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- match all attribute values --> <xsl:template match="aggregate/content//@*"> <xsl:comment><xsl:value-of select="."/></xsl:comment> <xsl:attribute name="{name()}"> <!-- now here I need to loop over the parameter name attributes and search each attribute, possibly *slow* --> <xsl:call-template name="substring-replace"> <xsl:with-param name="search-for" select=""/> <xsl:with-param name="replace-with" select="blah"/> <xsl:with-param name="input" select="."/> </xsl:call-template> </xsl:attribute> </xsl:template> <xsl:template name="substring-replace"> <xsl:param name="input"/> <xsl:param name="search-for"/> <xsl:param name="replace-with"/> <xsl:comment><xsl:value-of select="$input"/><xsl:value-of select="$search-for"/><xsl:value-of select="$replace-with"/></xsl:comment> <xsl:choose> <!-- empty search string produces infinite loop --> <xsl:when test="$search-for=''"> <xsl:value-of select="$input"/> </xsl:when> <xsl:when test="contains($input, $search-for)"> <xsl:value-of select="substring-before($input, $search-for)"/> <xsl:value-of select="$replace-with"/> <xsl:call-template name="substring-replace"> <xsl:with-param name="input" select="substring-after($input,$search-for)"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$input"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> -----Original Message----- From: Markus Abt [mailto:abt@xxxxxxxx] Sent: Mittwoch, 6. August 2003 17:19 To: 'xsl-list@xxxxxxxxxxxxxxxxxxxxxx' Subject: AW: [xsl] selecting everything below a node Hi Jorg, if you don't want to modify parts of it, you can use: <xsl:copy-of select="/aggregate/content"/> Adjust the xpath to your needs. If you want to modify some nodes, use the identity transformation: <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> Then use specific templates to do the modifications. Regards, Markus __________________________ Markus Abt Comet Computer GmbH http://www.comet.de ---------- Von: Jorg Heymans Gesendet: Mittwoch, 6. August 2003 16:43 An: 'xsl-list@xxxxxxxxxxxxxxxxxxxxxx' Betreff: [xsl] selecting everything below a node Hi list, Given following xml <aggregate> <request> many children here </request> <content> .many children here </content> </aggregate> How do I extract the whole <content> tree (nodes + attributes) into a different document? Regards Jorg 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 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
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] selecting everything belo, Jorg Heymans | Thread | RE: [xsl] selecting everything belo, Jorg Heymans |
[xsl] substitute with <br/>, Alexander Czernay | Date | RE: [xsl] XSLT document() function!, Michael Kay |
Month |