Subject: RE: [xsl] Replace values based on external files From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Fri, 14 Jan 2005 09:54:54 -0000 |
This needs an extension function such as dyn:evaluate, because you need to evaluate XPath expressions that aren't hard-coded in the stylesheet. You probably want the variant of this in Saxon called saxon:evaluate-node(), which is designed specifically to handle XPath expressions in source XML documents, and takes the namespace context for the XPath expression from the element node in which it is contained. Implementing this efficiently is not easy, because you don't want to copy the whole source document each time you find a node whose value needs to be replaced. In effect you want to build a list of nodes that need to be changed, together with their replacement values, and then you want to do a single scan of the source document testing each node to see if it is in this list. Unfortunately the intermediate data structure - a mapping from nodes to replacement values - is not easily represented in the XPath data model. I'd try doing it using generate-id(), something like this: <xsl:variable name="source" select="/"> <xsl:variable name="replacements"> <xsl:for-each select="replace"> <replace> <xsl:for-each select="$source/saxon:evaluate-node(current()/xpath)"> <node><xsl:value-of select="generate-id(.)"/></node> </xsl:for-each> <xsl:copy-of select="with"/> </replace> </xsl:for-each> </xsl:variable> <xsl:key name="n" match="node" use="."/> <xsl:template match="*"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:variable name="replacement" select="$replacements/key('n', generate-id(current()))"/> <xsl:choose> <xsl:when test="$replacement"> <xsl:value-of select="$replacement/../with"/> </xsl:when> <xsl:otherwise> <xsl:apply-templates/> </ </ </ <xsl:template match="@*"> <xsl:variable name="replacement" select="$replacements/key('n', generate-id(current()))"/> <xsl:choose> <xsl:when test="$replacement"> <xsl:attribute name="{name(.)}" namespace="{namespace-uri(.)}" select="$replacement/../with"/> </xsl:when> <xsl:otherwise> <xsl:copy/> </ </ </ Another way of tackling this problem would be by generating a stylesheet to do it. That would remove the need for extension functions. Michael Kay http://www.saxonica.com/ > -----Original Message----- > From: Robert Soesemann [mailto:rsoesemann@xxxxxxxxxxx] > Sent: 14 January 2005 09:28 > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > Subject: [xsl] Replace values based on external files > > Hello, > > I need to implement a XSL that will replace text values in file1.xml > based on replacement information in file2.xml. > > file2.xml provides an XPath that points to an attribute / > element value > and a replacement value. The XML has the form of: > > <mapping> > <!-- should replace @attribute1 value that are 'foo' of > all element1 > elements in file1.xml with 'bar'--> > <replace> > <xpath>//element1/@attribute1[.='foo']</xpath> > <with>bar</with> > </replace> > <replace> > ... <!-- other replacement operations --> > </replace> > ... > </mapping> > > Is there an easy way to dynamically generate replacement > instructions in > my XSL. I thought of extracting replacement information from file2.xml > with the document function. > > > Any help is much welcome. > > Robert
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Replace values based on exter, Robert Soesemann | Thread | RE: [xsl] Replace values based on e, Robert Soesemann |
[xsl] Replace values based on exter, Robert Soesemann | Date | RE: [xsl] Replace values based on e, Robert Soesemann |
Month |