1 <?xml version=
"1.0" encoding=
"UTF-8"?>
5 // svg2xaml_standalone.xslt
7 // This stylesheet converts svg to xaml, without using the node-set function
13 // Andreia Gaita (avidigal@novell.com)
15 // Copyright 2007 Novell, Inc.
17 // Permission is hereby granted, free of charge, to any person obtaining
18 // a copy of this software and associated documentation files (the
19 // "Software"), to deal in the Software without restriction, including
20 // without limitation the rights to use, copy, modify, merge, publish,
21 // distribute, sublicense, and/or sell copies of the Software, and to
22 // permit persons to whom the Software is furnished to do so, subject to
23 // the following conditions:
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
28 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 <xsl:stylesheet version=
"1.0"
39 xmlns:
xsl=
"http://www.w3.org/1999/XSL/Transform"
40 xmlns:
svg=
"http://www.w3.org/2000/svg"
41 xmlns:
xlink=
"http://www.w3.org/1999/xlink"
42 xmlns:
xaml=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation"
43 exclude-result-prefixes=
"svg xsl xaml xlink"
46 <xsl:output method=
"xml" version=
"1.0" encoding=
"UTF-8" indent=
"yes"/>
48 <!--- maps svg names into xaml names -->
49 <xsl:variable name=
"mappings">
51 <mapping name=
"id" value=
"Name" type=
"attribute"/>
53 <mapping name=
"stroke" value=
"Stroke" type=
"attribute"/>
54 <mapping name=
"fill" value=
"Fill" type=
"attribute">
57 <mapping name=
"fill" parent=
"text" value=
"Foreground" type=
"attribute"/>
58 <mapping name=
"transform" value=
"RenderTransform" type=
"element" template=
"transform" prefixParent=
"true"/>
59 <mapping name=
"gradientTransform" value=
"RenderTransform" type=
"element" template=
"transform" prefixParent=
"true"/>
60 <mapping name=
"viewBox" value=
"RenderTransform" type=
"element" template=
"viewBox" prefixParent=
"true" names=
"x y Width Height" filter=
"local"/>
62 <mapping name=
"stroke-linejoin" value=
"StrokeLineJoin" type=
"attribute"/>
63 <mapping name=
"stroke-width" value=
"StrokeThickness" type=
"attribute"/>
64 <mapping name=
"stroke-linecap" value=
"StrokeEndLineCap" type=
"attribute" />
66 <mapping name=
"font-size" value=
"FontSize" type=
"attribute"/>
67 <mapping name=
"text-anchor" value=
"AlignmentX" type=
"attribute">
68 <value name=
"middle" value=
"Centered"></value>
70 <mapping name=
"x" value=
"Canvas.Left" type=
"attribute" filter=
"local"/>
71 <mapping name=
"y" value=
"Canvas.Top" type=
"attribute" filter=
"local"/>
73 <mapping name=
"x" value=
"X" parent=
"viewBox" type=
"attribute" filter=
"local" op=
"mul" opval=
"-1">
76 <mapping name=
"y" value=
"Y" parent=
"viewBox" type=
"attribute" filter=
"local" op=
"mul" opval=
"-1">
79 <mapping name=
"rx" value=
"Width" type=
"attribute" filter=
"local"/>
80 <mapping name=
"ry" value=
"Height" type=
"attribute" filter=
"local"/>
81 <mapping name=
"cx" value=
"Canvas.Left" type=
"attribute" filter=
"local"/>
82 <mapping name=
"cy" value=
"Canvas.Top" type=
"attribute" filter=
"local"/>
83 <mapping name=
"r" type=
"attribute"/>
84 <mapping name=
"r" value=
"X" parent=
"radialGradient" prefix=
"Radius" type=
"attribute"/>
85 <mapping name=
"offset" value=
"Offset" type=
"attribute" />
86 <mapping name=
"stop-color" value=
"Color" type=
"attribute" />
87 <mapping name=
"style" value=
"Style" type=
"attribute" />
88 <mapping name=
"d" value=
"Data" type=
"attribute" />
89 <mapping name=
"xlink:href" />
91 <mapping name=
"path" value=
"Path" type=
"element"/>
92 <mapping name=
"text" value=
"Text" type=
"element"/>
93 <mapping name=
"ellipse" value=
"Ellipse" type=
"element"/>
94 <mapping name=
"circle" value=
"Ellipse" type=
"element"/>
95 <mapping name=
"linearGradient" value=
"LinearGradientBrush" type=
"element"/>
96 <mapping name=
"radialGradient" value=
"RadialGradientBrush" type=
"element"/>
97 <mapping name=
"stop" value=
"GradientStop" type=
"element"/>
104 <xsl:template match=
"/">
105 <xsl:apply-templates />
108 <xsl:template match=
"svg:svg">
110 <xsl:variable name=
"inheritable-settings">
112 <xsl:call-template name=
"parse-attributes">
113 <xsl:with-param name=
"node" select=
"."/>
114 <xsl:with-param name=
"filter" select=
"'inherit'"/>
119 <xsl:variable name=
"inheritable-attributes">
121 <xsl:copy-of select=
"$inheritable-settings/settings/@*"/>
125 <xsl:variable name=
"local-settings">
127 <xsl:call-template name=
"parse-attributes">
128 <xsl:with-param name=
"name" select=
"'Canvas'"/>
129 <xsl:with-param name=
"node" select=
"."/>
130 <xsl:with-param name=
"filter" select=
"'local'"/>
135 <Canvas xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
137 <!-- output the local settings -->
138 <xsl:copy-of select=
"$local-settings/settings/@*"/>
140 <!-- search and output the node element settings, adding the Canvas. prefix-->
141 <xsl:for-each select=
"$inheritable-settings/settings/*">
142 <xsl:element name=
"Canvas.{name(.)}">
143 <xsl:copy-of select=
"@*"/>
144 <xsl:copy-of select=
"child::*"/>
148 <xsl:copy-of select=
"$local-settings/settings/child::*"/>
150 <xsl:apply-templates>
151 <xsl:with-param name=
"defaults" select=
"$inheritable-attributes"/>
152 </xsl:apply-templates>
158 <!-- A element - for links -->
159 <xsl:template match=
"svg:a">
160 <!-- inherited transformations -->
161 <xsl:param name=
"transform"/>
162 <!-- inherited defaults -->
163 <xsl:param name=
"defaults" />
165 <xsl:apply-templates>
166 <xsl:with-param name=
"transform" select=
"$transform"/>
167 <xsl:with-param name=
"defaults" select=
"$defaults"/>
168 </xsl:apply-templates>
171 <!-- g element - children inherit these values and transforms -->
172 <xsl:template match=
"svg:g">
173 <xsl:param name=
"transform"/>
174 <xsl:param name=
"defaults" />
176 <!-- gather up the default values for the children to have -->
177 <xsl:variable name=
"defs">
179 <!-- get the parent's defaults, if any -->
180 <xsl:copy-of select=
"$defaults/defaults/@*"/>
181 <xsl:call-template name=
"parse-attributes">
182 <xsl:with-param name=
"node" select=
"."/>
184 <xsl:copy-of select=
"$defaults/defaults/*"/>
188 <!-- get any transformations and store to send to the children -->
189 <xsl:variable name=
"local-transform">
191 xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
192 <xsl:call-template name=
"split">
193 <xsl:with-param name=
"template" select=
"'transform'"/>
194 <xsl:with-param name=
"str" select=
"@transform"/>
195 <xsl:with-param name=
"separator"><xsl:value-of select=
"' '"/></xsl:with-param>
197 <xsl:if test=
"$transform">
198 <xsl:copy-of select=
"$transform/xaml:TransformGroup/*"/>
205 <!-- if there are more than 1 children, it's a group transform, send the whole $transform value -->
206 <xsl:when test=
"@transform and count(child::*) > 1">
207 <xsl:apply-templates>
208 <xsl:with-param name=
"transform" select=
"$local-transform"/>
209 <xsl:with-param name=
"defaults" select=
"$defs"/>
210 </xsl:apply-templates>
215 <!-- if there is only one children or there is no transformation to apply, cut out the TransformGroup tag (it might be empty, which is good) -->
216 <xsl:apply-templates>
217 <xsl:with-param name=
"transform" select=
"$local-transform/xaml:TransformGroup/*"/>
218 <xsl:with-param name=
"defaults" select=
"$defs"/>
219 </xsl:apply-templates>
228 <!-- drawing children - they're all the same, really -->
229 <xsl:template match=
"svg:path | svg:circle | svg:ellipse | svg:rect | svg:line | svg:polyline | svg:polygon">
230 <!-- inherited transformations -->
231 <xsl:param name=
"transform"/>
232 <!-- inherited defaults -->
233 <xsl:param name=
"defaults" />
235 <xsl:variable name=
"name" select=
"name(.)"/>
236 <xsl:element name=
"{$mappings/mappings/mapping[@name=$name]/@value}" xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
238 <!-- process the attributes and store them in a variable for later use -->
239 <xsl:variable name=
"local-attributes">
241 <xsl:call-template name=
"parse-attributes">
242 <xsl:with-param name=
"name" select=
"$mappings/mappings/mapping[@name=$name]/@value"/>
243 <xsl:with-param name=
"node" select=
"."/>
248 <!-- inherit parents attributes -->
249 <xsl:copy-of select=
"$defaults/defaults/@*"/>
250 <!-- output this node's attributes -->
251 <xsl:copy-of select=
"$local-attributes/xaml:attributes/@*"/>
253 <xsl:if test=
"not(@fill) and not($defaults/defaults/@Fill) and not($local-attributes/xaml:attributes/@Fill)">
254 <xsl:attribute name=
"Fill">#
000</xsl:attribute>
257 <!-- check if there are transforms inherited from the parent and aggregate them all into one -->
259 <xsl:when test=
"$local-attributes/xaml:attributes/*[contains(name(.), 'Transform')]">
260 <xsl:element name=
"{$mappings/mappings/mapping[@name=$name]/@value}.RenderTransform"
261 xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
263 <xsl:when test=
"$transform and $transform[name(.)='TransformGroup']">
265 xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
267 <xsl:copy-of select=
"$transform/*"/>
268 <xsl:copy-of select=
"$local-attributes/xaml:attributes/*[contains(name(.), 'Transform')]"/>
273 <xsl:if test=
"$transform">
274 <xsl:copy-of select=
"$transform"/>
276 <xsl:copy-of select=
"$local-attributes/xaml:attributes/*[contains(name(.), 'Transform')]"/>
282 <xsl:if test=
"$transform">
283 <xsl:element name=
"{$mappings/mappings/mapping[@name=$name]/@value}.RenderTransform" namespace=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
284 <xsl:copy-of select=
"$transform"/>
290 <!-- output remaning attributes that got turned into elements and that were not outputted in the above group -->
291 <xsl:copy-of select=
"$local-attributes/xaml:attributes/*[not(contains(name(.), 'Transform'))]"/>
296 <xsl:template match=
"svg:text">
297 <!-- inherited transformations -->
298 <xsl:param name=
"transform"/>
299 <!-- inherited defaults -->
300 <xsl:param name=
"defaults" />
302 <xsl:variable name=
"attributes">
304 <xsl:call-template name=
"parse-attributes">
305 <xsl:with-param name=
"node" select=
"."/>
310 <TextBlock xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
311 <xsl:copy-of select=
"$attributes/attributes/@*[name(.) != 'Text']"/>
312 <Run><xsl:value-of select=
"$attributes/attributes/@Text"/></Run>
317 <xsl:template match=
"svg:defs" mode=
"defaults">
318 <xsl:apply-templates mode=
"defaults" />
321 <xsl:template match=
"svg:*" mode=
"defaults">
322 <xsl:variable name=
"name" select=
"name()"/>
323 <xsl:if test=
"$mappings/mappings/mapping[@name=$name and @type='element']">
324 <xsl:element name=
"{$mappings/mappings/mapping[@name=$name and @type='element']/@value}" xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
325 <xsl:call-template name=
"parse-attributes">
326 <xsl:with-param name=
"name" select=
"$mappings/mappings/mapping[@name=$name and @type='element']/@value"/>
327 <xsl:with-param name=
"node" select=
"."/>
330 <xsl:apply-templates mode=
"defaults" />
335 <!-- DEFAULT TEMPLATES
336 These are just default implementations that don't really do anything.
339 <xsl:template match=
"svg:*">
340 <!-- inherited transformations -->
341 <xsl:param name=
"transform"/>
342 <!-- inherited defaults -->
343 <xsl:param name=
"defaults" />
345 <xsl:apply-templates>
346 <xsl:with-param name=
"transform" select=
"$transform"/>
347 <xsl:with-param name=
"defaults" select=
"$defaults"/>
348 </xsl:apply-templates>
351 <xsl:template match=
"text()" mode=
"#all">
354 <!-- ######## HELPER TEMPLATES ####### -->
356 <!-- transform template - to turn transform="..." properties into Transform* elements -->
357 <xsl:template name=
"transform">
358 <xsl:param name=
"name"/>
359 <xsl:param name=
"str"/>
360 <xsl:param name=
"prefix"/>
362 <!-- check what the separator is on the list of values to process -->
363 <xsl:variable name=
"separator">
365 <xsl:when test=
"contains($str, ',')">,
</xsl:when>
366 <xsl:otherwise> </xsl:otherwise>
370 <!-- each transformation outputs slightly different nodes, so check one by one -->
372 <xsl:if test=
"starts-with($str, 'translate')">
373 <xsl:element name=
"{prefix}TranslateTransform" namespace=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
375 <xsl:call-template name=
"splitCoords">
376 <xsl:with-param name=
"str" select=
"substring-before(substring-after($str, 'translate('), ')')"/>
377 <xsl:with-param name=
"separator"><xsl:value-of select=
"string($separator)"/></xsl:with-param>
382 <xsl:if test=
"starts-with($str, 'rotate')">
383 <xsl:element name=
"RotateTransform" namespace=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
384 <xsl:attribute name=
"Angle"><xsl:value-of select=
"substring-before(substring-after($str, 'rotate('), ')')"/></xsl:attribute>
385 <xsl:if test=
"../@rx">
386 <xsl:attribute name=
"CenterX"><xsl:value-of select=
"../@rx"/></xsl:attribute>
388 <xsl:if test=
"../@ry">
389 <xsl:attribute name=
"CenterY"><xsl:value-of select=
"../@ry"/></xsl:attribute>
391 <xsl:if test=
"../@r">
392 <xsl:attribute name=
"CenterX"><xsl:value-of select=
"../@r"/></xsl:attribute>
393 <xsl:attribute name=
"CenterY"><xsl:value-of select=
"../@r"/></xsl:attribute>
398 <xsl:if test=
"starts-with($str, 'scale')">
399 <xsl:element name=
"ScaleTransform" namespace=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
400 <xsl:call-template name=
"splitCoords">
401 <xsl:with-param name=
"str" select=
"substring-before(substring-after($str, 'scale('), ')')"/>
402 <xsl:with-param name=
"prefix" select=
"'Scale'"/>
403 <xsl:with-param name=
"separator" select=
"string($separator)"/>
407 <xsl:if test=
"starts-with($str, 'matrix')">
408 <xsl:element name=
"MatrixTransform" namespace=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
409 <xsl:attribute name=
"Matrix"><xsl:value-of select=
"substring-before(substring-after($str, 'matrix('), ')')"/></xsl:attribute>
415 <!-- template to process the viewBox property of the svg and turn it into properties of the canvas -->
416 <xsl:template name=
"viewBox">
417 <xsl:param name=
"mapping"/>
418 <xsl:param name=
"str"/>
419 <xsl:param name=
"prefix"/>
421 <xsl:variable name=
"attributes">
423 <xsl:call-template name=
"match-name-value">
424 <xsl:with-param name=
"names"><xsl:value-of select=
"$mapping/@names"/></xsl:with-param>
425 <xsl:with-param name=
"values"><xsl:value-of select=
"$str"/></xsl:with-param>
426 <xsl:with-param name=
"separator" select=
"' '"/>
431 <xsl:copy-of select=
"$attributes/attributes/@Width"/>
432 <xsl:copy-of select=
"$attributes/attributes/@Height"/>
434 <xsl:variable name=
"transform">
436 <xsl:call-template name=
"parse-attributes">
437 <xsl:with-param name=
"node" select=
"$attributes/attributes"/>
442 <xsl:if test=
"$transform and count($transform/transform/@*) > 0 or count($transform/transform/*) > 0">
443 <xsl:element name=
"{$prefix}RenderTransform" namespace=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
444 <xsl:element name=
"TranslateTransform" namespace=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
445 <xsl:copy-of select=
"$transform/transform/@*"/>
446 <xsl:copy-of select=
"$transform/transform/*"/>
454 <!-- template to build attribute nodes with pair values separated by $separator with names separated by $separator -->
455 <xsl:template name=
"match-name-value">
456 <xsl:param name=
"names"/>
457 <xsl:param name=
"values"/>
458 <xsl:param name=
"separator"/>
461 <xsl:when test=
"contains($names, $separator)">
462 <xsl:attribute name=
"{substring-before($names, $separator)}"><xsl:value-of select=
"substring-before($values, $separator)"/></xsl:attribute>
464 <xsl:call-template name=
"match-name-value">
465 <xsl:with-param name=
"names" select=
"substring-after($names, $separator)"/>
466 <xsl:with-param name=
"values" select=
"substring-after($values, $separator)"/>
467 <xsl:with-param name=
"separator" select=
"$separator"/>
471 <xsl:attribute name=
"{$names}"><xsl:value-of select=
"$values"/></xsl:attribute>
476 <xsl:template name=
"splitCoords">
477 <xsl:param name=
"mapping"/>
478 <xsl:param name=
"str"/>
479 <xsl:param name=
"prefix"/>
480 <xsl:param name=
"separator"/>
481 <xsl:param name=
"n" select=
"1"/>
484 <!--- stupid contains thinks an empty space is equal to no space at all... -->
485 <xsl:when test=
"contains($str,$separator) and substring-after($str, $separator) != $str">
487 <xsl:when test=
"$n = 1 and (not($mapping) or ($mapping/ignore != substring-before($str, $separator)))">
488 <xsl:attribute name=
"{$prefix}X"><xsl:value-of select=
"substring-before($str, $separator)"/></xsl:attribute>
490 <xsl:when test=
"$n = 2 and (not($mapping) or ($mapping/ignore != substring-before($str, $separator)))">
491 <xsl:attribute name=
"{$prefix}Y"><xsl:value-of select=
"substring-before($str, $separator)"/></xsl:attribute>
493 <xsl:when test=
"$n = 3 and (not($mapping) or ($mapping/ignore != substring-before($str, $separator)))">
494 <xsl:attribute name=
"{$prefix}Width"><xsl:value-of select=
"substring-before($str, $separator)"/></xsl:attribute>
496 <xsl:when test=
"$n = 4 and (not($mapping) or ($mapping/ignore != substring-before($str, $separator)))">
497 <xsl:attribute name=
"{$prefix}Height"><xsl:value-of select=
"substring-before($str, $separator)"/></xsl:attribute>
501 <!-- recurse again cutting out the part we've processed -->
502 <xsl:call-template name=
"splitCoords">
503 <xsl:with-param name=
"mapping" select=
"$mapping"/>
504 <xsl:with-param name=
"str" select=
"substring-after($str, $separator)"/>
505 <xsl:with-param name=
"prefix" select=
"$prefix"/>
506 <xsl:with-param name=
"separator" select=
"$separator"/>
507 <xsl:with-param name=
"n" select=
"$n + 1"/>
511 <!-- this is the last one, end recursion -->
513 <xsl:when test=
"$n = 1 and (not($mapping) or ($mapping/ignore != $str))">
514 <xsl:attribute name=
"{$prefix}X"><xsl:value-of select=
"$str"/></xsl:attribute>
516 <xsl:when test=
"$n = 2 and (not($mapping) or ($mapping/ignore != $str))">
517 <xsl:attribute name=
"{$prefix}Y"><xsl:value-of select=
"$str"/></xsl:attribute>
519 <xsl:when test=
"$n = 3 and (not($mapping) or ($mapping/ignore != $str))">
520 <xsl:attribute name=
"{$prefix}Width"><xsl:value-of select=
"$str"/></xsl:attribute>
522 <xsl:when test=
"$n = 4 and (not($mapping) or ($mapping/ignore != $str))">
523 <xsl:attribute name=
"{$prefix}Height"><xsl:value-of select=
"$str"/></xsl:attribute>
531 <!-- call a template by name -->
532 <xsl:template name=
"process-template">
533 <xsl:param name=
"mapping"/>
534 <xsl:param name=
"name"/>
535 <xsl:param name=
"template"/>
536 <xsl:param name=
"str"/>
537 <xsl:param name=
"prefix"/>
540 <xsl:when test=
"$template = 'transform'">
541 <xsl:call-template name=
"transform">
542 <xsl:with-param name=
"name" select=
"$name"/>
543 <xsl:with-param name=
"str" select=
"$str"/>
544 <xsl:with-param name=
"prefix" select=
"$prefix"/>
547 <xsl:when test=
"$template = 'viewBox'">
548 <xsl:call-template name=
"viewBox">
549 <xsl:with-param name=
"mapping" select=
"$mapping"/>
550 <xsl:with-param name=
"name" select=
"$name"/>
551 <xsl:with-param name=
"str" select=
"$str"/>
552 <xsl:with-param name=
"prefix" select=
"$prefix"/>
559 <!-- helper template to recursively split a string and call another template to output each component -->
560 <xsl:template name=
"split">
561 <xsl:param name=
"template"/>
562 <xsl:param name=
"str"/>
563 <xsl:param name=
"separator"/>
565 <xsl:when test=
"contains($str,$separator)">
566 <xsl:call-template name=
"process-template">
567 <xsl:with-param name=
"template" select=
"$template"/>
568 <xsl:with-param name=
"str" select=
"substring-before($str,$separator)"/>
570 <xsl:call-template name=
"split">
571 <xsl:with-param name=
"template" select=
"$template"/>
572 <xsl:with-param name=
"str" select=
"substring-after($str,$separator)"/>
573 <xsl:with-param name=
"separator" select=
"$separator"/>
577 <xsl:call-template name=
"process-template">
578 <xsl:with-param name=
"template" select=
"$template"/>
579 <xsl:with-param name=
"str" select=
"$str"/>
586 <!-- helper template to recursively process a name-value pair in $str separated by $separator, and
587 call the attributes template to turn it into an attribute -->
588 <xsl:template name=
"name-value">
589 <xsl:param name=
"str"/>
590 <xsl:param name=
"separator"/>
591 <xsl:param name=
"separator2" select=
"':'"/>
594 <xsl:variable name=
"input" select=
"normalize-space($str)"/>
596 <xsl:if test=
"$input != ''">
598 <!--- if there are more to process, recurse -->
599 <xsl:when test=
"contains($input,$separator)">
600 <xsl:variable name=
"attribute">
602 <xsl:attribute name=
"{normalize-space(substring-before(substring-before($input,$separator), $separator2))}"><xsl:value-of select=
"normalize-space(substring-after(substring-before($input,$separator), $separator2))"/></xsl:attribute>
606 <xsl:call-template name=
"parse-attributes">
607 <xsl:with-param name=
"node" select=
"$attribute/attribute"/>
610 <!-- recursiveness, here we go -->
611 <xsl:call-template name=
"name-value">
612 <xsl:with-param name=
"str" select=
"substring-after($input,$separator)"/>
613 <xsl:with-param name=
"separator" select=
"$separator"/>
614 <xsl:with-param name=
"separator2" select=
"$separator2"/>
618 <!-- we're at the last one, stop here -->
620 <xsl:variable name=
"attribute">
622 <xsl:attribute name=
"{normalize-space(substring-before($input, $separator2))}"><xsl:value-of select=
"normalize-space(substring-after($input, $separator2))"/></xsl:attribute>
625 <xsl:call-template name=
"parse-attributes">
626 <xsl:with-param name=
"node" select=
"$attribute/attribute"/>
634 <!-- transform attributes by finding their correspondence in the mappings table. If they're marked as elements or need
635 specific templates to be processed, call those -->
636 <xsl:template name=
"parse-attributes">
637 <xsl:param name=
"name"/>
638 <xsl:param name=
"node"/>
639 <xsl:param name=
"filter"/>
640 <xsl:param name=
"parent"/>
642 <xsl:variable name=
"prefix">
643 <xsl:if test=
"$name"><xsl:value-of select=
"$name"/>.
</xsl:if>
646 <xsl:variable name=
"local-parent">
648 <xsl:when test=
"$parent"><xsl:value-of select=
"$parent"/>.
</xsl:when>
649 <xsl:otherwise><xsl:value-of select=
"name(.)"/></xsl:otherwise>
653 <xsl:for-each select=
"$node/@*">
654 <xsl:variable name=
"attname" select=
"name(.)"/>
657 <xsl:variable name=
"mapping">
659 <xsl:when test=
"$mappings/mappings/mapping[@name=$attname and @parent=$local-parent]"><xsl:copy-of select=
"$mappings/mappings/mapping[@name=$attname and @parent=$local-parent]" /></xsl:when>
660 <xsl:otherwise><xsl:copy-of select=
"$mappings/mappings/mapping[@name=$attname]" /></xsl:otherwise>
664 <xsl:if test=
"$mapping/mapping and (not($filter) or ($mapping/mapping[@parent=$local-parent and @filter = $filter]) or ($mapping/mapping[not(@parent) and @filter = $filter]) or ($mapping/mapping[not(@filter)]))">
668 <!-- process attributes that need to be processed with a specific template (like transforms) -->
669 <xsl:when test=
"$mapping/mapping[@template != '']">
670 <xsl:call-template name=
"process-template">
671 <xsl:with-param name=
"mapping" select=
"$mapping/mapping"/>
672 <xsl:with-param name=
"name" select=
"$attname"/>
673 <xsl:with-param name=
"template" select=
"$mapping/mapping/@template"/>
674 <xsl:with-param name=
"str" select=
"."/>
675 <xsl:with-param name=
"prefix" select=
"$prefix"/>
679 <!-- process normal attributes -->
683 <!-- first do the custom attributes -->
684 <xsl:when test=
"$attname='r' and $local-parent = 'circle'">
685 <xsl:if test=
"not(../@cx)">
686 <xsl:attribute name=
"Canvas.Left"><xsl:value-of select=
". * -1"/></xsl:attribute>
689 <xsl:if test=
"not(../@cy)">
690 <xsl:attribute name=
"Canvas.Top"><xsl:value-of select=
". * -1"/></xsl:attribute>
693 <xsl:attribute name=
"Width"><xsl:value-of select=
". * 2"/></xsl:attribute>
694 <xsl:attribute name=
"Height"><xsl:value-of select=
". * 2"/></xsl:attribute>
697 <xsl:when test=
"$attname='r' and $local-parent != 'circle'">
698 <xsl:attribute name=
"{$mapping/mapping/@prefix}X">
699 <xsl:call-template name=
"output-attribute-value">
700 <xsl:with-param name=
"mapping" select=
"$mapping/mapping"/>
701 <xsl:with-param name=
"value" select=
"."/>
704 <xsl:attribute name=
"{$mapping/mapping/@prefix}Y">
705 <xsl:call-template name=
"output-attribute-value">
706 <xsl:with-param name=
"mapping" select=
"$mapping/mapping"/>
707 <xsl:with-param name=
"value" select=
"."/>
711 <xsl:when test=
"$attname='rx'">
712 <xsl:attribute name=
"Width"><xsl:value-of select=
". * 2"/></xsl:attribute>
713 <xsl:attribute name=
"Canvas.Left"><xsl:value-of select=
". * -1"/></xsl:attribute>
715 <xsl:when test=
"$attname='ry'">
716 <xsl:attribute name=
"Height"><xsl:value-of select=
". * 2"/></xsl:attribute>
717 <xsl:attribute name=
"Canvas.Top"><xsl:value-of select=
". * -1"/></xsl:attribute>
719 <xsl:when test=
"$attname='cx'">
720 <xsl:attribute name=
"Canvas.Left">
722 <xsl:when test=
"../@rx"><xsl:value-of select=
". - ../@rx"/></xsl:when>
723 <xsl:otherwise><xsl:value-of select=
". - ../@r"/></xsl:otherwise>
727 <xsl:when test=
"$attname='cy'">
728 <xsl:attribute name=
"Canvas.Top">
730 <xsl:when test=
"../@ry"><xsl:value-of select=
". - ../@ry"/></xsl:when>
731 <xsl:otherwise><xsl:value-of select=
". - ../@r"/></xsl:otherwise>
736 <xsl:when test=
"$attname='style'">
737 <xsl:variable name=
"style">
739 <xsl:call-template name=
"name-value">
740 <xsl:with-param name=
"str" select=
"."/>
741 <xsl:with-param name=
"separator" select=
"';'"/>
746 <xsl:variable name=
"defs" select=
"//svg:defs"/>
747 <xsl:variable name=
"style-elements">
749 <xsl:for-each select=
"$style/style/@*">
751 <xsl:when test=
"contains(., 'url')">
752 <xsl:element name=
"{$name}.{name()}" xmlns=
"http://schemas.microsoft.com/winfx/2006/xaml/presentation">
753 <xsl:variable name=
"ref" select=
"substring-before(substring-after(., 'url(#'), ')')"/>
754 <xsl:apply-templates select=
"$defs/*[@id=$ref]" mode=
"defaults"/>
758 <xsl:copy-of select=
"."/>
765 <xsl:copy-of select=
"$style-elements/style-elements/@*" />
766 <xsl:copy-of select=
"$style-elements/style-elements/*" />
769 <xsl:when test=
"$attname='xlink:href'">
770 <xsl:variable name=
"defs" select=
"//svg:defs"/>
771 <xsl:variable name=
"style-elements">
773 <xsl:variable name=
"ref" select=
"substring-after(., '#')"/>
774 <xsl:apply-templates select=
"$defs/*[@id=$ref]" mode=
"defaults"/>
778 <xsl:call-template name=
"recursive-copy">
779 <xsl:with-param name=
"node" select=
"$style-elements/style-elements" />
784 <!-- if it's not a custom one, check the mappings -->
785 <!-- if there is a mapping for this attribute (ignore parent) and the value is not marked to ignore -->
786 <xsl:when test=
"not($mapping/mapping/ignore = normalize-space(.))">
787 <xsl:attribute name=
"{$mapping/mapping/@value}">
789 <xsl:when test=
"$mapping/mapping/value[@name=current()]"><xsl:value-of select=
"$mapping/mapping/value[@name=current()]/@value"/></xsl:when>
791 <xsl:call-template name=
"output-attribute-value">
792 <xsl:with-param name=
"mapping" select=
"$mapping/mapping"/>
793 <xsl:with-param name=
"value" select=
"."/>
807 <!-- output any text value -->
808 <xsl:if test=
"text() and $mappings/mappings/mapping[@name=$local-parent]">
809 <xsl:attribute name=
"{$mappings/mappings/mapping[@name=$local-parent]/@value}"><xsl:value-of select=
"."/></xsl:attribute>
814 <xsl:template name=
"output-attribute-value">
815 <xsl:param name=
"mapping"/>
816 <xsl:param name=
"value"/>
819 <xsl:when test=
"$mapping/@op = 'mul'"><xsl:value-of select=
"$value * $mapping/@opval"/></xsl:when>
820 <xsl:when test=
"$mapping/@op = 'add'"><xsl:value-of select=
"$value + $mapping/@opval"/></xsl:when>
821 <xsl:when test=
"$mapping/@op = 'sub'"><xsl:value-of select=
"$value - $mapping/@opval"/></xsl:when>
822 <xsl:when test=
"$mapping/@op = 'div'"><xsl:value-of select=
"$value div $mapping/@opval"/></xsl:when>
823 <xsl:otherwise><xsl:value-of select=
"$value"/></xsl:otherwise>
827 <xsl:template name=
"recursive-copy">
828 <xsl:param name=
"node" />
830 <xsl:for-each select=
"$node/*">
832 <xsl:when test=
"count(child::*) = 0"><xsl:copy-of select=
"." /></xsl:when>
834 <xsl:copy-of select=
"@*"/>
835 <xsl:call-template name=
"recursive-copy">
836 <xsl:with-param name=
"node" select=
"." />
843 <!-- ######## END OF HELPER TEMPLATES ####### -->