Navegación e inspección SVG – Aspose.SVG for .NET

A veces es necesario inspeccionar el contenido de los archivos SVG, por ejemplo, obtener información sobre el archivo, los elementos y la jerarquía. Aspose.SVG for .NET API es totalmente compatible con las especificaciones SVG oficiales y se puede utilizar para atravesar el modelo de objetos de documento (DOM) SVG. La API admite una amplia gama de funcionalidades de navegación e inspección de los contenidos SVG.

En esta sección descubrirás:

Puede descargar los ejemplos completos y los archivos de datos desde GitHub. Encontrará información sobre la descarga desde GitHub y la ejecución de ejemplos en la sección Cómo ejecutar los ejemplos.

Ver contenido SVG

La forma más sencilla de inspeccionar el contenido del documento es mirar el contenido como una cadena. Las propiedades InnerHTML y OuterHTML de la clase Element devuelven un fragmento de XML (o HTML) que representa el elemento y su contenido. Están desarrollados precisamente para ver contenido SVG como una cadena. El siguiente ejemplo de código muestra cómo ver el contenido del archivo bezier-curves.svg en la consola.

 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	

Extraer información sobre un elemento SVG específico

El siguiente ejemplo muestra cómo extraer información sobre un elemento SVG particular de un archivo 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    }

En el ejemplo, el uso de la propiedad DocumentElement permite el acceso directo al elemento <svg> del documento. El método GetElementsByTagName() de la clase Element devuelve una NodeList de todos los elementos descendientes con un nombre de etiqueta determinado; en este caso el elemento devuelto es el primer elemento <g>. La propiedad FirstElementChild devuelve el primer nodo de elemento secundario de este elemento. En el ejemplo, el primer elemento secundario del elemento <g> es el elemento <rect>, para el cual se imprimen los valores de Height y Width.

Inspección de un documento SVG y sus elementos

Aspose.SVG contiene una lista de métodos que se basan en las Especificaciones transversales de elementos. Puede realizar una inspección detallada del documento y sus elementos utilizando la API ( shapes.svg). El siguiente ejemplo de código muestra el uso generalizado de las funciones de Element Traversal.

 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    }

El elemento <svg> es un contenedor y se utiliza como el elemento más externo de los documentos SVG. Para señalar el elemento <svg>, puedes aplicar varias formas:

1var svgElement = document.RootElement;

La propiedad LastElementChild de la clase Documento devuelve el último elemento hijo del elemento <svg>. Es el elemento <g>. Según el fragmento de código anterior, el elemento variable se sobrecarga nuevamente y la propiedad FirstElementChild devuelve el primer hijo del elemento <g>. Es el elemento <rect>.

Uso de filtro personalizado

La API Aspose.SVG le permite definir filtros personalizados y usarlos para iterar sobre los elementos del documento como se muestra en el siguiente ejemplo de código:

 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    }

El método CreateNodeIterator(Node, Int64, INodeFilter) de la interfaz IDocumentTraversal crea un nuevo iterador con raíz en el Node especificado (en nuestro ejemplo, es el document). Como parámetros, el método toma Node, el indicador Int64 que especifica los tipos de nodo para el iterador y INodeFilter que se utilizará (en nuestro ejemplo, es RectFilter()).

La clase RectFilter hereda de la clase NodeFilter el método AcceptNode(Node n). El método toma un Node y prueba si pasa el filtro o no; el método devuelve un short que indica si se encuentra el nodo o no.

En el iterador, utilizamos el método NextNode() de la interfaz INodeIterator para acceder a todos los nodos del documento. La primera llamada a NextNode() devuelve el primer nodo y mueve la posición del iterador en el conjunto. La propiedad OuterHTML de la clase Element devuelve el contenido del elemento que se imprimirá.

Puede descargar los ejemplos completos y los archivos de datos desde GitHub. Encontrará información sobre la descarga desde GitHub y la ejecución de ejemplos en la sección Cómo ejecutar los ejemplos.

Editar SVG usando el selector CSS

Aspose.SVG for .NET también implementa la especificación CSS Selector que le permite navegar por el documento utilizando un estilo similar a CSS.

El método QuerySelector(selector) de la clase Element le permite obtener el primer elemento dentro del documento que coincide con el selector especificado. El método QuerySelectorAll(selector) toma como parámetro el selector de consultas y devuelve una NodeList de todos los elementos que coinciden con el selector. Con los elementos resultantes, puedes realizar diversas manipulaciones: cambiar su texto, atributos, estilos CSS, etc.

En los siguientes ejemplos, utilizamos los métodos QuerySelector() y QuerySelectorAll() para navegar a través de un documento SVG y buscar los elementos necesarios.

Ejemplo 1

En el ejemplo 1, editamos el archivo fuente owl.svg: es la imagen SVG del búho dibujada por los elementos de ruta y círculo.

Usando el selector 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    }

Puede ver y guardar el archivo SVG editado siguiendo el enlace: owl-edited1.svg.

Ejemplo 2

En este ejemplo, mostramos cómo utilizar el Selector de CSS para navegar por un documento con fines de edición. Continuamos editando el archivo fuente owl.svg:

Creamos un nuevo elemento <g>, le agregamos los atributos comunes para los niños (serán nuevos ojos cuadrados) y lo agregamos como el último elemento secundario en el elemento <svg> (ver Editar archivo SVG); usando el método QuerySelectorAll("g:first-child > circle") encontramos todos los círculos en el primer elemento <g>; luego creamos elementos <rect> con los atributos de tamaño, agregamos rectángulos en el segundo elemento <g> y eliminamos los elementos circulares.

El siguiente fragmento de código demuestra cómo realizar esta tarea:

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

En la figura: la imagen fuente (a), una imagen editada según el Ejemplo 1 (b), una imagen editada según el Ejemplo 2 (c).

Texto “Imágenes de búho originales y dos editadas”

En los ejemplos anteriores, tomamos el archivo fuente owl.svg y editamos algunos elementos. Intentamos decorar los ojos y las alas del búho de varias maneras usando las funciones API de navegación e inspección de Aspose.SVG. Puede ver y guardar el archivo SVG editado siguiendo el enlace: owl-edited2.svg.

La consulta XPath ( XML Path Language), a menudo denominada simplemente XPath, es un lenguaje de consulta que se utiliza para consultar datos de documentos. Se basa en una representación DOM del documento SVG y selecciona nodos según varios criterios. La sintaxis de las expresiones XPath es bastante simple y, lo que es más importante, es fácil de leer y de soportar.

Aspose.SVG también tiene una potente implementación de especificaciones XPath junto con especificaciones transversales. Esto le permite utilizar XPath Query para navegar por el documento ( shapes.svg) como se muestra en el siguiente ejemplo de código:

 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    }

Puede descargar los ejemplos completos y los archivos de datos desde GitHub.

Encontrará información sobre la descarga desde GitHub y la ejecución de ejemplos en la sección Cómo ejecutar los ejemplos.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.