Jump to content

Trying to transform SVG into custom XML

Recommended Posts

I'm trying to transform a SVG-file into another XML-file using XSLT and the C# class XslCompiledTransform. This is my SVG

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg"	 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"	 version="1.1" baseProfile="full"	 width="800mm" height="600mm"><rect x="10" y="10" width="90" height="40" /></svg>

This is my C#-Code

static void Main(string[] args)		{			string xmlSource = args[0];			string xmlOutput = args[1];			string xsltFile = args[2]; 			// if xslt or soure contains a DTD:			XmlReaderSettings xmlReadSet = new XmlReaderSettings();			xmlReadSet.DtdProcessing = DtdProcessing.Parse;			xmlReadSet.ValidationType = ValidationType.Schema;			XslCompiledTransform xslt = new XslCompiledTransform(); 			//			XmlWriterSettings xmlWriteSet = new XmlWriterSettings();			xmlWriteSet.ConformanceLevel = ConformanceLevel.Auto; 			//			xslt.Load(xsltFile);			xslt.Transform(XmlReader.Create(xmlSource, xmlReadSet), XmlWriter.Create(xmlOutput, xmlWriteSet)); 		}

And this is my XSLT

<?xml version="1.0" encoding="utf-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"	xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">	<xsl:output method="xml" version="1.0" indent="yes" encoding="utf-8" omit-xml-declaration="no"/> 	<xsl:template match="/">	  <xsl:element name="Redlining">		<xsl:attribute name="hash">???</xsl:attribute>		<xsl:attribute name="version">4.1</xsl:attribute> 		<xsl:element name="BoundingBox">		  <xsl:attribute name="xMin">???</xsl:attribute>		  <xsl:attribute name="yMin">???</xsl:attribute>		  <xsl:attribute name="xMax">???</xsl:attribute>		  <xsl:attribute name="yMax">???</xsl:attribute>		</xsl:element> 		<xsl:element name="GeometryHolder" />		<xsl:apply-templates select="rect"/>	  </xsl:element>	</xsl:template>   <xsl:template match="rect">	<xsl:element name="RectangleHolder">	  <xsl:element name="Sector">		<xsl:attribute name="type">sector</xsl:attribute>		<xsl:element name="Coordinate">		  <xsl:attribute name="x">			<xsl:value-of select="@x + @width"/>		  </xsl:attribute>				</xsl:element>	  </xsl:element>	</xsl:element>  </xsl:template></xsl:stylesheet>

And this is what I get

<Redlining hash="???" version="4.1"><BoundingBox xMin="???" yMin="???" xMax="???" yMax="???" /><GeometryHolder /></Redlining>

As you can see the template "rect" is omitted. I got the advice to use this

...	  <xsl:apply-templates select=".//*[local-name()='rect']"/>	  ...    ...   <xsl:template match="*[local-name()='rect']">   ...

Then I get what I want. But I don't understand what is wrong with my attempt since it seems that all the tutorials do it like my attempt. Or am I missing something? Thanks for reading, Stefan

Edited by alpman
Link to post
Share on other sites

SVG is in a namespace. You must specify that namespace URI in the XSLT document. The prefix is irrelevant, as long as the URIs match.In other words, another way to get what you want is:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"        xmlns:msxsl="urn:schemas-microsoft-com:xslt"        xmlns:svg="http://www.w3.org/2000/svg"        exclude-result-prefixes="msxsl svg">...        <xsl:apply-templates select=".//svg:rect"/>        ...    <xsl:template match="svg:rect">

Link to post
Share on other sites

Thanks for your answer but why this:

		<xsl:apply-templates select=".//svg:rect"/>

Why isn't it enough to write
		<xsl:apply-templates select="svg:rect"/>

since I try to match the root node in the first template?

Edited by alpman
Link to post
Share on other sites

The "select" in apply-templates is relative to whatever node the template matched.The root node (the one matched by "/") is like an invisible node surrounding the whole document. The only element directly accessible from it is SVG's root element - the "svg:svg" element. Therefore,

<xsl:apply-templates select="svg:rect"/>

wouldn't match anything, since the rect is within the "svg:svg" element.When at the root node, you may as well shorten


to just


since the result would be the same, but if you were applying the template on an element, the first form would only select all rect elements within that element, whereas the second would always select all rect elements across the whole document.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...