Навигация и проверка SVG – Aspose.SVG для .NET

Иногда вам необходимо проверить содержимое файлов SVG, например, получить информацию о файле, элементах и ​​иерархии. Aspose.SVG для .NET API полностью совместим с официальными спецификациями SVG и может использоваться для работы с объектной моделью документов SVG (DOM). API поддерживает широкий спектр функций навигации и проверки содержимого SVG.

В этом разделе вы узнаете:

Вы можете загрузить полные примеры и файлы данных с GitHub. О загрузке с GitHub и запуске примеров вы узнаете из раздела Как запускать примеры.

Просмотр содержимого SVG

Самый простой способ проверить содержимое документа – просмотреть содержимое как строку. Свойства InnerHTML и OuterHTML класса Element возвращают фрагмент XML (или HTML), который представляет элемент и его содержимое. Они разработаны именно для просмотра содержимого SVG в виде строки. В следующем примере кода показано, как просмотреть содержимое файла bezier-curves.svg в консоли.

 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

Навигация и проверка SVG с использованием DOM

Извлечение информации о конкретном элементе SVG

В следующем примере показано, как извлечь информацию о конкретном элементе SVG из файла 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    }

В этом примере использование свойства DocumentElement обеспечивает прямой доступ к элементу <svg> документа. Метод GetElementsByTagName() класса Element возвращает NodeList всех элементов-потомков с заданным именем тега; в этом случае возвращаемым элементом является первый элемент <g>. Свойство FirstElementChild возвращает первый узел дочернего элемента этого элемента. В этом примере первым дочерним элементом элемента <g> является элемент <rect>, для которого печатаются значения ширины и высоты.

Проверка документа SVG и его элементов

Aspose.SVG содержит список методов, основанных на Спецификациях обхода элементов. Выполнить детальную проверку документа и его элементов можно с помощью API ( shapes.svg). В следующем примере кода показано обобщенное использование функций обхода элементов.

 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    }

Элемент <svg> является контейнером и используется как самый внешний элемент документов SVG. Чтобы указать элемент <svg>, вы можете применить несколько способов:

1var svgElement = document.RootElement;

Свойство LastElementChild класса Document возвращает последний дочерний элемент элемента <svg>. Это элемент <g>. Согласно приведенному выше фрагменту кода, элемент переменной снова перегружается, а свойство FirstElementChild возвращает первого дочернего элемента элемента <g>. Это элемент <rect>.

Использование пользовательского фильтра

API Aspose.SVG позволяет вам определять собственные фильтры и использовать их для перебора элементов документа, как показано в следующем примере кода:

 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    }

где класс RectFilter определяется следующим образом:

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    }

Метод CreateNodeIterator(Node, Int64, INodeFilter) интерфейса IDocumentTraversal создает новый итератор с корнем в указанном Node (в нашем примере это document). В качестве параметров метод принимает флаг Node, Int64, определяющий типы узлов для итератора, и INodeFilter (в нашем примере это RectFilter()).

Класс RectFilter наследует от класса NodeFilter метод AcceptNode(Node n). Метод принимает узел и проверяет, проходит ли он фильтр или нет; метод возвращает короткое сообщение, указывающее, найден ли узел или нет.

В итераторе мы используем метод NextNode() интерфейса INodeIterator для доступа ко всем узлам документа. Первый вызов NextNode() возвращает первый узел и перемещает позицию итератора в наборе. Свойство OuterHTML класса Element возвращает содержимое элемента, которое будет напечатано.

Вы можете загрузить полные примеры и файлы данных с GitHub. О загрузке с GitHub и запуске примеров вы узнаете из раздела Как запускать примеры.

Редактировать SVG с помощью селектора CSS

Aspose.SVG для .NET также реализует спецификацию CSS Selector, которая позволяет вам перемещаться по документу.

Метод QuerySelector(selector) класса Element позволяет получить первый элемент в документе, соответствующий указанному селектору. Метод QuerySelectorAll(selector) принимает в качестве параметра селектор запроса и возвращает NodeList всех элементов, соответствующих селектору. С получившимися элементами можно производить различные манипуляции: менять его текст, атрибуты, стили CSS и так далее.

В следующих примерах мы используем методы QuerySelector() и QuerySelectorAll() для навигации по документу SVG и поиска необходимых элементов.

Пример 1

В примере 1 мы редактируем исходный файл owl.svg – это SVG-изображение совы, нарисованное элементами пути и круга.

Использование селектора CSS:

 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    }

Посмотреть и сохранить отредактированный SVG-файл можно по ссылке – owl-edited1.svg.

Пример 2

В этом примере мы покажем, как использовать селектор CSS для навигации по документу в целях редактирования. Продолжаем редактировать исходный файл owl.svg:

Мы создаем новый элемент <g>, добавляем в него общие атрибуты для дочерних элементов (это будут новые квадратные глаза) и добавляем его в качестве последнего дочернего элемента в элементе <svg> (см. Редактирование файла SVG); используя метод QuerySelectorAll(“g:first-child > circle”), мы находим все круги в первом элементе <g>; затем мы создаем элементы <rect> с атрибутами размера, добавляем прямоугольники во второй элемент <g> и удаляем элементы круга.

Следующий фрагмент кода демонстрирует, как реализовать эту задачу:

 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");

На рисунке: исходная картинка (а), отредактированная картинка по примеру 1 (b), отредактированная картинка по примеру 2 (c).

Text «Оригинальное и два отредактированных изображения совы»

В приведенных выше примерах мы берем исходный файл owl.svg и редактируем некоторые элементы. Глаза и крылья совы мы попытались украсить различными способами, используя функции навигации и проверки API Aspose.SVG. Посмотреть и сохранить отредактированный SVG-файл можно по ссылке – owl-edited2.svg.

Навигация по SVG с помощью запроса XPath

XPath Query ( XML Path Language), часто называемый просто XPath, представляет собой язык запросов, используемый для запроса данных из документов. Он основан на DOM-представлении документа SVG и выбирает узлы по различным критериям. Синтаксис выражений XPath довольно прост и, что более важно, его легко читать и поддерживать.

Aspose.SVG также имеет мощную реализацию спецификаций XPath наряду со спецификациями обхода. Это позволит вам использовать XPath Query для навигации по документу ( shapes.svg), как показано в следующем примере кода:

 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    }

Вы можете загрузить полные примеры и файлы данных с GitHub.

О загрузке с GitHub и запуске примеров вы узнаете из раздела Как запускать примеры.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.