Click here to Skip to main content
15,888,351 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I'm trying to transform a SVG-file into another XML-file using XSLT and the C# class XslCompiledTransform

This is my SVG
XML
<?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
C#
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-File:

XML
<?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:
XML
<Redlining hash="???" version="4.1"><BoundingBox xMin="???" yMin="???" xMax="???" yMax="???" /><GeometryHolder /></Redlining>


I don't understand why the xml declaration is omitted, why the xml is not indented and, the most important part, what I'm doing wrong with the definition and calling of the template for the rect elements.

Can anyone help me please?
Posted
Updated 20-Aug-12 4:43am
v2

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


[EDIT]
If this does not help, you may try the following:
XML
   ...
   <xsl:apply-templates select=".//*[local-name()='rect']"/>
   ...

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


Maybe, there is a more elegant way, though, to ignore the element name spaces.

I had some issues while running this in VS2010. If I remove the DOCTYPE part and if I take away the namespaces, the first version works fine and instantly. With the original svg file content, VS2010 takes 10-15 seconds to run that (and only the second variant works).
[/EDIT]

Cheers
Andi
 
Share this answer
 
v2
Comments
Alpman 21-Aug-12 4:25am    
Thanks, Andi. I observed the time issue with the DOCTYPE, too.

Can you please explain what was wrong with my attempt? I thought that with my first template I address the root node (i. e. the tag <svg>) and calling xsl:apply-templates select="rect" will select all "rect" child elements and apply the specified template.

Bye,

Stefan
Andreas Gieriet 21-Aug-12 7:00am    
The root node is "/", the root element is "/svg", not "/".
Since there is a leading "/", it is an absolute XPath.
See w3schools.com: XPath Tutorial for a quick introduction on XPath.
Cheers
Andi
According to an answer I got at w3schools.com I had to include the svg namespace in the XSLT and add "svg" to exclude-result-prefixes:

XML
...
<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"
>
...


Then I can address the templates like this:

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

...
<xsl:template match="svg:rect">
...
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900