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:
- cómo ver un contenido SVG como una cadena;
- cómo realizar una inspección detallada del documento y sus elementos utilizando la API;
- qué formas existen de obtener información sobre un elemento particular de un archivo SVG;
- sobre el uso de filtros personalizados para iterar sobre los elementos del documento;
- cómo navegar por el documento utilizando CSS Selector o XPath Query.
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
Navegación e inspección SVG usando DOM
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:
- La propiedad
DocumentElement
de la clase Document da acceso directo al elemento<svg>
del documento. En el fragmento de código anterior, usamos esta manera. - La propiedad
RootElement
de la clase SVGDocument devuelve el elemento raíz<svg>
en la jerarquía del documento. Para indicar el elemento<svg>
, puede aplicar el siguiente código:
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.
- encontramos todos los elementos circulares en el documento SVG y cambiamos sus propiedades – hacemos grandes ojos azules para el búho;
- Buscamos el elemento del camino para un ala del búho y lo decoramos.
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:
- en la primera parte del Ejemplo 2, los ojos redondos del búho se cambiarán a cuadrados y se volverán a colorear.
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");
- en la segunda parte del Ejemplo 2, la trayectoria del ala del búho cambiará de curva a polilínea y se volverá a colorear.
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).
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.
Navegar SVG con consulta XPath
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.