using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.Linq;
public class XmlReader : MonoBehaviour
{
public enum Rects
{
WIDTH, HEIGHT, X, Y, COLOR, ANGLE
}
void Start ()
{
ParseXml();
}
private void ParseXml()
{
XDocument document = XDocument.Load(@"C:\Users\mysvg\Documents\my.svg");
XNamespace ns = "http://www.w3.org/2000/svg";
var list = document.Root.Descendants(ns + "rect").Select(e => new {
Style = e.Attribute("fill").Value,
Angle = e.Attribute("transform").Value,
Width = e.Attribute("width").Value,
Height = e.Attribute("height").Value,
X = e.Attribute("x").Value
});
foreach (var item in list)
{
string result = string.Format("Width: {0}, Height: {1}, X: {2}", item.Width, item.Height, item.X);
}
}
// Update is called once per frame
void Update ()
{
}
}
svg文件格式为:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 744.09448819 1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="drawing.svg"
inkscape:export-filename="C:\Users\adili_000\Desktop\drawing.png"
inkscape:export-xdpi="125"
inkscape:export-ydpi="125">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="470.51389"
inkscape:cy="692.09768"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid4172" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="opacity:1;fill:#00c8fc;fill-opacity:0.98823529;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4155"
width="45.714287"
height="30"
x="37.387959"
y="115.30345" />
<rect
style="opacity:1;fill:#00c8fc;fill-opacity:0.98823529;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4155-5"
width="45.714287"
height="30"
x="91.899246"
y="115.40621" />
<rect
<path
sodipodi:type="star"
style="opacity:1;fill:#f1c8fc;fill-opacity:0.98823529;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path4841"
sodipodi:sides="8"
sodipodi:cx="288.21429"
sodipodi:cy="396.29076"
sodipodi:r1="21.58555"
sodipodi:r2="10.792775"
sodipodi:arg1="1.0471976"
sodipodi:arg2="1.4398967"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 299.00707,414.98441 -9.38404,-7.9932 -6.99549,10.1496 -0.98347,-12.28755 -12.12341,2.23029 7.99319,-9.38404 -10.1496,-6.99549 12.28756,-0.98347 -2.23029,-12.12341 9.38404,7.99319 6.99549,-10.1496 0.98347,12.28756 12.12341,-2.23029 -7.99319,9.38403 10.14959,6.99549 -12.28755,0.98348 z" />
</g>
</svg>
我无法弄清楚如何做的一些问题。
第一个问题是如何获得每个rect填充的填充值我的意思是颜色:style =&#34;不透明度:1;填充:#00c8fc;填充不透明度:0.98823529;填充 - 所以我需要获取/提取#00c8fc。
另一个值是变换的6个数字,其中一些变换在底部变换:我没有添加svg的全部内容,但是底部的一些内容是:
<rect
style="opacity:1;fill:#00c8fc;fill-opacity:0.98823529;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4155-5-6-56-6-2"
width="27.153143"
height="13.716971"
x="79.204071"
y="477.30438"
transform="matrix(0.9672488,-0.25383017,0.25383017,0.9672488,0,0)" />
我需要得到6个数字:0.9672488,-0.25383017,0.25383017,0.9672488,0,0
更新
为了获得样式部分,我添加了一行:
Style = e.Attribute("style").Value.Substring(16,6),
现在我如何将transform / matrix 6数字作为6个int变量? 然后我需要用6个数字进行一些计算。
问题是并非每个rect都在底部进行了转换: 我试着添加一行:
Transform= e.Attribute("transform").Value.Substring(18, 43),
但是获得null异常,因为不是每个rect都有变换。
如何提取已转换6个数字的矩形?例如:
变换=&#34;矩阵(0.98125852,-0.1926959,0.1926959,0.98125852,0,0)&#34;
所以我需要在6个数字中加入6个int变量:0.98125852,-0.1926959,0.1926959,0.98125852,0,0
答案 0 :(得分:1)
我使用xml linq和正则表达式以及字典。工作得很好
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
Rect.rectangles = doc.Descendants().Where(x => x.Name.LocalName == "rect").Select(x => new Rect()
{
style = Rect.GetStyle((string)x.Attribute("style")),
id = (string)x.Attribute("id"),
width = (double)x.Attribute("width"),
height = (double)x.Attribute("width"),
x = (double?)x.Attribute("width"),
y = (double?)x.Attribute("width"),
transform = x.Attribute("transform") == null ? null : (object)Rect.GetTransform((string)x.Attribute("transform"))
}).ToList();
}
}
public class Rect
{
public static List<Rect> rectangles { get; set; }
public Dictionary<string, string> style { get; set; }
public string id { get; set; }
public double width { get; set; }
public double height { get; set; }
public double? x { get; set; }
public double? y { get; set; }
public object transform { get; set; }
public static Dictionary<string, string> GetStyle(string styles)
{
string pattern = @"(?'name'[^:]+):(?'value'.*)";
string[] splitArray = styles.Split(new char[] { ';' });
Dictionary<string, string> style = splitArray.Select(x => Regex.Match(x, pattern))
.GroupBy(x => x.Groups["name"].Value, y => y.Groups["value"].Value)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
return style;
}
public static KeyValuePair<double, double> GetTransform(string matrix)
{
string pattern = @"[-+]?\d+\.\d+";
MatchCollection matches = Regex.Matches(matrix, pattern);
KeyValuePair<double, double> kp = new KeyValuePair<double, double>(
double.Parse(matches[0].Value),
double.Parse(matches[0].Value)
);
return kp;
}
}
}
答案 1 :(得分:0)
为了获得样式部分,我添加了一行:Style = e.Attribute(&#34; style&#34;)。Value.Substring(16,6),
这假设fill
将从第16位开始,由于许多原因可能不正确(例如 style =&#34; opacity:0.987; fill = ...&#34; < / em>)并且该值将是6个字符长( style =&#34;不透明度:1;填充=红色; ...&#34; )不正确。这应该会更好:
Style = e.Attribute("style")?.Value.Split(';').Where(property => property.StartsWith("fill:")).Select(property => property.Substring(5)).FirstOrDefault(),
所以我需要在6个数字中加入6个int变量:0.98125852,-0.1926959,0.1926959,0.98125852,0,0
首先,由于这些数字是浮点数(不是整数),你当然需要浮点数或双变量。
其次,为了防止在不存在transform属性时出现异常,请使用?.
运算符,当value为null时停止表达式求值:
Angle = ParseTransformMatrix(e.Attribute("transform")?.Value),
并使用此方法从属性字符串中提取6个转换矩阵参数:
static double[] ParseTransformMatrix(string transform)
{
if (String.IsNullOrWhiteSpace(transform))
return null;
if (!(transform.StartsWith("matrix(") && transform.EndsWith(")")))
return null;
return transform
.Substring(7, transform.Length - 8)
.Split(',')
.Select(s => Double.Parse(s, System.Globalization.CultureInfo.InvariantCulture))
.ToArray();
}
有些人可能更喜欢使用Regex解析此类字符串。但我并不喜欢这样的人。
另请注意,我的答案仅适用于此特定svg文件,但可能不适用于其他文件,因为解析svg文件可能是非常复杂的任务,当考虑所有可能的功能时(级联样式,某些如果有几种不同的方式,符号实例等,可以设置属性。)