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:
- how to view an SVG content as a string;
- how to perform a detailed inspection of the document and its elements using the API;
- what ways are for information about a particular element from the SVG file;
- about custom filters usage for iterating over the document elements;
- how to navigate over the document by using CSS Selector or XPath Query.
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
Navigation & Inspection SVG using DOM
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:
- The
DocumentElement
property of the Document class gives direct access to the<svg>
element of the document. In the code snippet above, we use this way. - The
RootElement
property of the SVGDocument class returns the root<svg>
element in the document hierarchy. To indicate the<svg>
element, you can apply the following code:
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:
- we find all circle elements in the SVG document and change their properties – make big blue eyes for the owl;
- we find the path element for a wing of the owl and decorate it.
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:
- in the first part of Example 2, the round eyes of the owl will be changed to square and recolored.
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");
- in the second part of Example 2, the owl wing’s path will be changed from the curve to polyline and recolored.
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).
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.
Navigate SVG with XPath Query
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.