导航 SVG – Navigation & Inspection SVG – Aspose.SVG for .NET
有时您需要检查 SVG 文件的内容,例如,获取有关文件、元素和层次结构的信息。 Aspose.SVG for .NET API 与官方 SVG 规范 完全兼容,可用于遍历 SVG 文档对象模型 (DOM)。该 API 支持 SVG 内容的各种导航和检查功能。
在本节中,您将了解:
- 如何以字符串形式查看 SVG 内容;
- 如何使用 API 对文档及其元素进行详细检查;
- 有哪些方法可以获取有关 SVG 文件中特定元素的信息;
- 关于迭代文档元素的自定义过滤器用法;
- 如何使用 CSS 选择器或 XPath 查询浏览文档。
查看 SVG 内容
检查文档内容的最简单方法是将内容视为字符串。
Element 类的属性 InnerHTML
和 OuterHTML
返回表示元素及其内容的 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
15
使用 DOM 导航和检查 SVG
提取有关特定 SVG 元素的信息
以下示例演示如何从文件 shapes.svg 中提取有关特定 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>
元素。
Element 类的方法
GetElementsByTagName() 返回具有给定标签名称的所有后代元素的 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>
元素,您可以应用几种方法:
- Document 类的
DocumentElement
属性提供对文档的<svg>
元素的直接访问。在上面的代码片段中,我们使用了这种方式。 - SVGDocument 类的
RootElement
属性返回文档层次结构中的根<svg>
元素。要指示<svg>
元素,您可以应用以下代码:
1var svgElement = document.RootElement;
Document 类的 LastElementChild
属性返回<svg>
元素的最后一个子元素。它是 <g>
元素。根据上面的代码片段,变量元素再次被重载,FirstElementChild
属性返回 <g>
元素的第一个子元素。它是 <rect>
元素。
自定义过滤器的使用
Aspose.SVG API 允许您定义自定义过滤器并使用它们来迭代文档元素,如以下代码示例所示:
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 }
IDocumentTraversal 接口的
CreateNodeIterator(Node, Int64, INodeFilter
) 方法创建一个以指定 Node
为根的新迭代器(在我们的示例中,它是 document
)。该方法采用 Node
、指定迭代器节点类型的 Int64
标志以及要使用的 INodeFilter
作为参数(在我们的示例中,它是 RectFilter()
)。
RectFilter 类继承自
NodeFilter 类的
AcceptNode(Node n
) 方法。该方法采用一个 Node
并测试它是否通过过滤器;该方法返回一个短值,指示是否找到该节点。
在迭代器中,我们使用
INodeIterator 接口的
NextNode() 方法来访问文档的所有节点。第一次调用 NextNode() 返回第一个节点并移动迭代器在集合中的位置。
Element 类的 OuterHTML
属性返回将要打印的元素的内容。
使用 CSS 选择器编辑 SVG
Aspose.SVG for .NET 还实现了 CSS 选择器规范,允许您使用类似 CSS 的样式来浏览文档。
Element 类的
QuerySelector(selector
) 方法允许您获取文档中与指定选择器匹配的第一个元素。
QuerySelectorAll(selector
) 方法将查询选择器作为参数,并返回与选择器匹配的所有元素的 NodeList。使用生成的元素,您可以进行各种操作:更改其文本、属性、CSS 样式等。
在以下示例中,我们使用 QuerySelector() 和 QuerySelectorAll() 方法在 SVG 文档中导航并搜索所需的元素。
实施例1
在示例 1 中,我们编辑源 owl.svg 文件 – 是由路径和圆形元素绘制的猫头鹰 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 }
您可以通过链接 – owl-edited1.svg 查看并保存编辑后的 SVG 文件。
实施例2
在此示例中,我们展示了如何使用 CSS 选择器来导航文档以进行编辑。我们继续编辑源 owl.svg 文件:
- 在示例2的第一部分中,猫头鹰的圆眼睛将更改为方形并重新着色。
我们创建一个新的 <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");
- 在示例 2 的第二部分中,猫头鹰翅膀的路径将从曲线更改为折线并重新着色。
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");
上图:源图片(a)、根据示例1编辑后的图片(b)、根据示例2编辑后的图片(c)。
在上面的示例中,我们采用源 owl.svg 文件并编辑一些元素。我们尝试使用导航和检查 Aspose.SVG API 函数以各种方式装饰猫头鹰的眼睛和翅膀。您可以通过链接 – owl-edited2.svg 查看并保存编辑后的 SVG 文件。
使用 XPath 查询导航 SVG
XPath 查询( XML 路径语言),通常简称为 XPath,是一种用于从文档查询数据的查询语言。它基于 SVG 文档的 DOM 表示,并根据各种标准选择节点。 XPath 表达式的语法非常简单,更重要的是,它易于阅读和支持。
Aspose.SVG 还具有强大的 XPath 规范实现以及遍历规范。这使您能够使用 XPath 查询来浏览文档 ( 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 }