XSLT: copying how to change content to replace certain elements?

I have an input XML document something like this:

<text> <p> Download the software from <link id="blah"> </p> </text> <links> <link id="blah"> <url>http://blah</url> </link> </links> 

And I would like my output to be:

 <text> <p> Download the software from <a href="http://blah"> http://blah </a> </p> </text> 

That is: I want to copy the existing nodes of the input document as is, but also replace some nodes (for example, <link> ) with the extended version: based on other information contained in the input document.

I tried using <xsl:copy .../> to first copy the fragment as follows:

 <xsl:variable name="frag"> <xsl:copy-of select="text"/> </xsl:variable> 

But when I output the variable like this:

 <xsl:value-of select="$frag"> 

Does the output not contain paragraph tags? So I'm not sure if xsl-copy copied the nodes or just text somehow?

If I add only the following (remove the "wrapper" <xsl:variable/> ), will it save the tags in the output?

 <xsl:copy-of select="text"/> 

But, of course, I need to first reassign this 'link' tag to the anchor tag ....

I did not even begin to figure out how then to replace the contents of the variable (in the new variable, of course) with the link information ....

+4
source share
2 answers

Try the following:

 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output indent="yes"/> <xsl:template match="links"/> <xsl:template match="*|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="link"> <xsl:variable name="link" select="normalize-space(//links/link[@id = current()/@id]/url)"/> <a href="{$link}"> <xsl:value-of select="$link"/> </a> </xsl:template> </xsl:stylesheet> 

With the following input:

 <?xml version="1.0" encoding="UTF-8"?> <texts> <text> <p> Download the software from <link id="blah"/> </p> </text> <links> <link id="blah"> <url>http://blah</url> </link> </links> </texts> 

You are getting:

 <?xml version="1.0" encoding="UTF-8"?> <texts> <text> <p> Download the software from <a href="http://blah">http://blah</a> </p> </text> </texts> 
+4
source

xsl:copy-of does not do what you want, because it creates an exact copy. Therefore, do not use it.

xsl:value-of does not do what you want, because it takes a string value and ignores all markup. Therefore, do not use it.

You need to use the “modified copy” template as shown in Vincent's answer. This uses two template rules [or more if necessary], a default rule that applies to nodes that need to be copied without modification, and a specific rule that applies to nodes that need to be changed.

+3
source

Source: https://habr.com/ru/post/1383092/


All Articles