Jump to content

Trying to transform SVG into custom XML


alpman

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 comment
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 comment
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 comment
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

.//svg:rect

to just

//svg:rect

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 comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...