Navigation & Inspection SVG – Aspose.SVG for .NET

Sometimes you need to inspect the content of SVG files, for example, get information about the file, the elements and the hierarchy. Aspose.SVG for .NET API is fully compatible with official SVG specifications and can be used to traverse the SVG Document Object Model (DOM). The API supports a wide range of navigation and inspection functionalities of the SVG contents.

In this section, you find out:

You can download the complete examples and data files from GitHub. About downloading from GitHub and running examples, you find out from the How to Run the Examples section.

View SVG Content

The easiest way to inspect the document content is to look at content as a string. The properties InnerHTML and OuterHTML of the Element class return a fragment of XML (or HTML) that represents the element and its contents. They are developed precisely for viewing SVG content as a string. The following code example shows how to view the content of bezier-curves.svg file in the console.

 1using Aspose.Svg;
 2using System.IO;
 3...
 4
 5    string documentPath = Path.Combine(DataDir, "bezier-curves.svg");
 6
 7	// Load an SVG document
 8	using (var document = new SVGDocument(documentPath))
 9	{
10	     var html = document.DocumentElement.OuterHTML;
11
12	     Console.WriteLine(html);
13	}	
14	// View the document content
15	

Extract Information about Specific SVG Element

The following example shows how to extract information about a particular SVG element from a file shapes.svg:

 1using Aspose.Svg;
 2using System.IO;
 3using System.Linq;
 4...
 5
 6    //Load a document from a file
 7    string documentPath = Path.Combine(DataDir, "shapes.svg");
 8
 9    using (var document = new SVGDocument(documentPath))
10    {
11        // Get the root svg element of the document
12    	var svg = document.DocumentElement;
13
14    	// Find the first child element with a given tag name
15        var g = svg.GetElementsByTagName("g").First() as SVGGElement;
16
17        var rect = g.FirstElementChild as SVGRectElement;
18
19        Console.WriteLine("Height: {0}", rect.Height);// 90
20        Console.WriteLine("Width: {0}", rect.Width); // 100
21    }

In the example, the DocumentElement property usage allows direct access to the <svg> element of the document. Method GetElementsByTagName() of the Element class returns a NodeList of all descendant elements with a given tag name; in this case the return element is the first <g> element. The FirstElementChild property returns the first child element node of this element. In the example, the first child in <g> element is the <rect> element, for which the Width and Height values are printed.

Inspection of an SVG Document and its Elements

Aspose.SVG contains a list of methods that are based on the Element Traversal Specifications. You can perform a detailed inspection of the document and its elements using the API ( shapes.svg). The following code sample shows the generalized usage of Element Traversal features.

 1using Aspose.Svg;
 2using System.IO;
 3...
 4
 5    // Load a document
 6	string documentPath = Path.Combine(DataDir, "shapes.svg");
 7
 8    using (var document = new SVGDocument(documentPath))
 9    {
10        var element = document.DocumentElement;
11        Console.WriteLine(element.TagName); // svg
12        
13        element = element.LastElementChild;
14        Console.WriteLine(element.TagName); // g
15
16        element = element.FirstElementChild;
17        Console.WriteLine(element.TagName); // rect
18    }

The <svg> element is a container, and it is used as the outermost element of SVG documents. To point the <svg> element, you can apply a few ways:

1var svgElement = document.RootElement;

The LastElementChild property of the Document class returns the last child element of the <svg> element. It is the <g> element. According to the code snippet above, the variable element is overloaded again, and FirstElementChild property returns the first child of the <g> element. It is the <rect> element.

Custom Filter Usage

Aspose.SVG API gives you to define custom filters and use them for iterating over the document elements as shown in the following code sample:

 1using Aspose.Svg;
 2using System.IO;
 3using Aspose.Svg.Dom;
 4using Aspose.Svg.Dom.Traversal.Filters;
 5...
 6
 7    using (var document = new SVGDocument(Path.Combine(DataDir, "shapes.svg")))
 8    {
 9        // Create a node iterator
10        using (var iterator = document.CreateNodeIterator(document, NodeFilter.SHOW_ALL, new RectFilter()))
11        {
12            Node node;
13            while ((node = iterator.NextNode()) != null)
14            {
15                Console.WriteLine((node as Element)?.OuterHTML);
16            }
17        }
18    }

where the RectFilter class is defined as follows:

1    public class RectFilter : NodeFilter
2    {
3        public override short AcceptNode(Node n)
4        {
5            return string.Equals("rect", n.NodeName) ? FILTER_ACCEPT : FILTER_REJECT;
6        }
7    }

The CreateNodeIterator(Node, Int64, INodeFilter)method of the IDocumentTraversal interface creates a new iterator rooted at the specified Node (in our example, it is the document). As parameters, the method takes Node, Int64 flag that specifies node types for the iterator, and INodeFilter to be used (in our example, it is the RectFilter()).

The RectFilter class inherits from the NodeFilter class the AcceptNode(Node n) method. The method takes a Node and tests if it passes the filter or not; the method returns a short indicating whether the node is found or not.

In the iterator, we use the NextNode() method of the INodeIterator Interface to access all the nodes of the document. The first call to the NextNode() returns the first node and moves the position of the iterator in the set. The OuterHTML property of the Element class returns the element’s content that will be printed.

You can download the complete examples and data files from GitHub. About downloading from GitHub and running examples, you find out from the How to Run the Examples section.

Edit SVG Using CSS Selector

Aspose.SVG for .NET also implements CSS Selector specification that allows you to navigate over the document by using CSS like style.

The QuerySelector(selector) method of the Element class allows you to get the first element within the document that matches the specified selector. The QuerySelectorAll(selector) method takes as a parameter the query selector and returns a NodeList of all the elements, which match the selector. With the resulting elements, you can make various manipulations: change its text, attributes, CSS styles, and so on.

In the following examples, we use the QuerySelector() and QuerySelectorAll() methods for navigation through an SVG document and search the needed elements.

Example 1

In Example 1, we edit the source owl.svg file – is the owl SVG picture drawn by the path and circle elements.

Using the CSS Selector:

 1using Aspose.Svg;
 2using System.IO;
 3using Aspose.Svg.Dom;
 4using Aspose.Svg.Collections;
 5...
 6
 7    using (var document = new SVGDocument(new Url("https://docs.aspose.com/svg/files/owl.svg")))
 8    {
 9        // Get root svg element of the document
10        var svgElement = document.RootElement;
11
12        // Find the first element that matches the specified in selector - g element
13        SVGGElement gElement = svgElement.QuerySelector("g") as SVGGElement;
14
15        // Find all circle elements in g element
16        NodeList circleNodes = gElement.QuerySelectorAll("circle");
17
18        // Make big blue eyes
19        foreach (Node circleNode in circleNodes)
20        {
21            SVGCircleElement circleElement = circleNode as SVGCircleElement;
22
23            circleElement.R.BaseVal.Value *= 1.5F;
24            circleElement.SetAttribute("stroke", "blue");
25        }
26
27        // Get path for an owl wing
28        SVGPathElement wingPath = gElement.QuerySelector("path:nth-child(2)") as SVGPathElement;
29    
30        // Apply style attributes to the wing
31        wingPath.SetAttribute("stroke-width", "16");
32        wingPath.SetAttribute("stroke-dasharray", "2 8");
33
34        document.Save(OutputDir + "owl-edited1.svg");
35    }

You can view and save the edited SVG file by following the link – owl-edited1.svg.

Example 2

In this example, we show how to use the CSS Selector to navigate a document for editing purposes. We continue to edit the source owl.svg file:

We create a new <g> element, add into it the common attributes for children (they will be new square eyes) and append it as the last child in <svg> element (see Edit SVG File); using QuerySelectorAll(“g:first-child > circle”) method we find all circles into the first <g> element; then we create <rect> elements with the size attributes, add rectangles into the second <g> element and remove the circle elements.

The following code snippet demonstrates how to realize this task:

 1using Aspose.Svg;
 2using System.IO;
 3using Aspose.Svg.Dom;
 4using Aspose.Svg.Collections;
 5...
 6
 7    // Create a new g element with style attributes and append it as the last child in svg element
 8    var gElement = (SVGGElement)document.CreateElementNS(SvgNamespace, "g");
 9    gElement.SetAttribute("fill", "none");
10    gElement.SetAttribute("stroke-width", "2");
11    svgElement.AppendChild(gElement);
12
13    // Find all circle elements from the first g element
14    NodeList circleNodes = svgElement.QuerySelectorAll("g:first-child > circle");
15
16    // Make square sky-blue eyes
17    foreach (Node circleNode in circleNodes)
18    {
19        var circleElement = circleNode as SVGCircleElement;
20
21        float cx = circleElement.Cx.BaseVal.Value;
22        float cy = circleElement.Cy.BaseVal.Value;
23        float r = circleElement.R.BaseVal.Value;
24
25        var rectElement = (SVGRectElement)document.CreateElementNS(SvgNamespace, "rect");
26        rectElement.X.BaseVal.Value = cx - r;
27        rectElement.Y.BaseVal.Value = cy - r;
28        rectElement.Width.BaseVal.Value = 3 * r;
29        rectElement.Height.BaseVal.Value = 3 * r;
30        rectElement.SetAttribute("stroke", "SkyBlue");
31
32        // Add the rectangle element into the last (new) g element 
33        gElement.AppendChild(rectElement);
34
35    	// Remove the circle elements
36        circleElement.Remove();
37    }
38    // Recolor last rectangle in the last (new) g element
39    Element lastRect = gElement.LastElementChild;
40    lastRect.SetAttribute("stroke", "red");
 1using Aspose.Svg;
 2using System.IO;
 3using Aspose.Svg.Dom;
 4using Aspose.Svg.Collections;
 5...
 6
 7    // Get path for owl body from the first g element
 8    Element bodyPath = (svgElement.QuerySelector("g:first-child") as SVGGElement).FirstElementChild;
 9    bodyPath.SetAttribute("stroke", "Teal");
10
11    // Get path for owl wing from the first g element
12    SVGPathElement wingPath = svgElement.QuerySelector("g:first-child > path:nth-child(2)") as SVGPathElement;
13
14    // Form new wing path data based on the old
15    string d = "";
16    foreach (SVGPathSeg pathSeg in wingPath.PathSegList)
17    {
18        if (pathSeg is SVGPathSegMovetoAbs)
19        {
20            SVGPathSegMovetoAbs pathSegMovetoAbs = pathSeg as SVGPathSegMovetoAbs;
21
22            d += string.Format(" M {0} {1}", pathSegMovetoAbs.X, pathSegMovetoAbs.Y);
23        }
24        if (pathSeg is SVGPathSegCurvetoCubicAbs)
25        {
26            SVGPathSegCurvetoCubicAbs pathSegCurvetoCubicAbs = pathSeg as SVGPathSegCurvetoCubicAbs;
27            
28            d += string.Format(
29                " L {0} {1} L {2} {3}",
30                (pathSegCurvetoCubicAbs.X1 + pathSegCurvetoCubicAbs.X2) / 2F,
31                (pathSegCurvetoCubicAbs.Y1 + pathSegCurvetoCubicAbs.Y2) / 2F,
32                pathSegCurvetoCubicAbs.X,
33                pathSegCurvetoCubicAbs.Y
34            );
35        }
36    }
37    // Set d attribute – new path data formation
38    wingPath.SetAttribute("d", d.Trim());
39    wingPath.SetAttribute("stroke", "Teal");
40
41    document.Save(OutputDir + "owl-edited2.svg");

On the figure: the source picture (a), an edited picture according to Example 1 (b), an edited picture according to Example 2 (c).

Text “Original and two edited owl images”

In the examples above, we take the source owl.svg file and edit some elements. We tried to decorate the eyes and wing of the owl in various ways using navigation and inspection Aspose.SVG API functions. You can view and save the edited SVG file by following the link – owl-edited2.svg.

XPath Query ( XML Path Language), often referred to simply as an XPath, is a query language used to query data from documents. It is based on a DOM representation of the SVG document and selects nodes by various criteria. The syntax of the XPath expressions is quite simple, and what is more important, it is easy to read and support.

Aspose.SVG also has powerful XPath Specifications implementation along with Traversal Specifications. This empowers you to use XPath Query to navigate over the document ( shapes.svg) as shown in the following code sample:

 1using Aspose.Svg;
 2using System.IO;
 3using Aspose.Svg.Dom;
 4using Aspose.Svg.Collections;
 5...
 6
 7    using (var document = new SVGDocument(Path.Combine(DataDir, "shapes.svg")))
 8    {
 9        //  Evaluate XPath expression
10        var xpathResult = document.Evaluate("//rect[@x='120']", document, null, (Dom.XPath.XPathResultType)XPathResultType.Any, null);
11
12        //  Get the next evaluated node
13        Console.WriteLine((xpathResult.IterateNext() as Element)?.OuterHTML); 
14    }

You can download the complete examples and data files from GitHub.

About downloading from GitHub and running examples, you find out from the How to Run the Examples section.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.