I must copy a <script>
node from xml to html, but I need to replace dinamically some lines of it, and also add new ones. So I need to search-and-replace strings while the entire node is copying.
XML example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
id="slot" width="320" height="245">
<script type="application/javascript"><![CDATA[
var a = 2;
var b = "abc";
var c = new Array(0,0,0);
alert("Input!");
]]></script>
<!-- here svg drawing tags -->
</svg>
HTML output example:
<html>
<head>
<title>Example!</title>
<script type="application/javascript">
var a = 2; <!---same as xml--->
var b = "def"; <!---modified--->
var c = new Array(0,0,0); <!---same as xml--->
alert("This is a new example!"); <!---modified--->
var new = "new var"; <!---new code--->
</script>
</head>
<body>
</body>
</html>
If it's much easy, I can use XTLS 2.0.
How can I do?
This transformation:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pSrcEdits">
<line num="2" act="del"/>
<line num="4" act="rep"
newLine="var c = new Array(1,1,1);"/>
<line num="5" act="ins"
newLine="/* Inserted comment */"/>
</xsl:param>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="svg:script/text()">
<xsl:variable name="vLines" select="tokenize(., '
?
')"/>
<xsl:sequence select="my:editLines($vLines, $pSrcEdits/*)"/>
</xsl:template>
<xsl:function name="my:editLines" as="xs:string*">
<xsl:param name="pLines" as="xs:string*"/>
<xsl:param name="pCommands" as="element()*"/>
<xsl:for-each select="$pLines">
<xsl:variable name="vLineNum" as="xs:integer"
select="position()"/>
<xsl:variable name="vCommand"
select="$pCommands[number(@num) eq $vLineNum]"/>
<xsl:sequence select="my:editSingle(., $vCommand)"/>
</xsl:for-each>
</xsl:function>
<xsl:function name="my:editSingle" as="xs:string?">
<xsl:param name="pLine" as="xs:string"/>
<xsl:param name="pCommand" as="element()?"/>
<xsl:sequence select=
"if(not($pCommand))
then concat($pLine, '
')
else
if($pCommand/@act eq 'del')
then ()
else
if($pCommand/@act eq 'rep')
then concat($pCommand/@newLine, '
')
else (: 'ins' :)
concat($pCommand/@newLine, '
', $pLine, '
')
"/>
</xsl:function>
</xsl:stylesheet>
when applied on the provided XML document:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
id="slot" width="320" height="245">
<script type="application/javascript"><![CDATA[
var a = 2;
var b = "abc";
var c = new Array(0,0,0);
alert("Input!");
]]></script>
<!-- here svg drawing tags -->
</svg>
produces the wanted result (all commands carried out and the script edited):
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
id="slot"
width="320"
height="245">
<script type="application/javascript">
var b = "abc";
var c = new Array(1,1,1);
/* Inserted comment */
alert("Input!");
</script>
<!-- here svg drawing tags -->
</svg>