Reputation: 11319
var list = document.Root.Descendants(ns + "rect").Select(e => new {
Style = e.Attribute("style").Value.Substring(16,6),
Transform= e.Attribute("transform").Value.Substring(18, 43),
Width = e.Attribute("width").Value,
Height = e.Attribute("height").Value,
X = e.Attribute("x").Value
});
Not every "rect" have the Attribute "transform". So i need somehow to check for null.
And how can i use Substring to get all the string i need ? If there is Attribute "transform" for example transform="matrix(0.98125852,-0.1926959,0.1926959,0.98125852,0,0)" then i need to extract the numbers: 0.98125852,-0.1926959,0.1926959,0.98125852,0,0 and put each number in a int variable. The problem is that the way i'm using substring now is fine if the last two numbers are 0,0 but they might be other numbers in other cases.
The code now:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
namespace SvgParser
{
public partial class Form1 : Form
{
public enum Rects
{
WIDTH, HEIGHT, X, Y, COLOR, ANGLE
}
public Form1()
{
InitializeComponent();
ColumnHeader columnHeader1 = new ColumnHeader();
columnHeader1.Text = "Column1";
this.listView1.Columns.AddRange(new ColumnHeader[] { columnHeader1 });
this.listView1.View = View.Details;
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("style").Value.Substring(16, 6),
Transform = 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);
if (item.Transform != null)
{
string transform = item.Transform;
// figure out the substring parameters
int start = "matrix(".Length;
int end = transform.LastIndexOf(")") - start;
// grab the values, by using split
string[] collection = transform.Substring(start, end).Split(',');
// an object to hold your results
List<decimal> results = new List<decimal>();
// iterate through the values (string) and try to convert it to a decimal
for (int i = 0; i < collection.Length; i++)
{
decimal.TryParse(collection[i], out decimal result);
results.Add(result);
}
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
But i'm getting now 3 errors. On the line:
decimal.TryParse(collection[i], out decimal result);
On the decimal and result:
Invalid expression term 'decimal'
And Syntax error, ',' expected
And error on the line:
results.Add(result);
On the result:
Argument 1: cannot convert from 'string' to 'decimal'
Then i change the out part to: out result
decimal.TryParse(collection[i], out result);
Now the error is:
Argument 2: cannot convert from 'out string' to 'out decimal'
Upvotes: 0
Views: 531
Reputation: 12858
Transform= e.Attribute("transform")?.Value.Substring(18, 43),
credit: https://stackoverflow.com/a/44340111/3645638
To answer your question on how to deal with the string, try this
// the string you want to grab the values from
string transform = "matrix(0.98125852,-0.1926959,0.1926959,0.98125852,0,0)";
// figure out the substring parameters
int start = "matrix(".Length;
int end = transform.LastIndexOf(")") - start;
// grab the values, by using split
string[] collection = transform.Substring(start,end).Split(',');
// an object to hold your results
List<decimal> results = new List<decimal>();
// iterate through the values (string) and try to convert it to a decimal
for (int i = 0; i < collection.Length; i++)
{
decimal.TryParse(collection[i], out decimal result);
results.Add(result);
}
this will result in a List<decimal>
called results
with the values
0.98125852
-0.1926959
0.1926959
0.98125852
0
0
As per your comments... This code block here
for (int i = 0; i < collection.Length; i++)
{
decimal.TryParse(collection[i], out decimal result);
results.Add(result);
}
is the equivalent to
for (int i = 0; i < collection.Length; i++)
{
decimal result; // note I am creating a new decimal (defaults to 0)
decimal.TryParse(collection[i], out result);
results.Add(result);
}
string result = string.Format("Width: {0}, Height: {1}, X: {2}", item.Width, item.Height, item.X);
you can't have string result
then declare decimal result
below it again... my example calls it transform
Upvotes: 3
Reputation: 519
Use safe navigation operator (?.):
var list = document.Root.Descendants(ns + "rect").Select(e => new {
Style = e.Attribute("style").Value?.Substring(16,6),
Transform= e.Attribute("transform").Value?.Substring(18, 43),
Width = e.Attribute("width").Value,
Height = e.Attribute("height").Value,
X = e.Attribute("x").Value
});
Upvotes: 0
Reputation: 13652
If you use C# 6.0, you can use the null conditional ?.
operator:
Transform= e.Attribute("transform")?.Value.Substring(18, 43),
Upvotes: 3
Reputation: 1178
You can use the ternary operator.
Transform = (e.Attribute("transform") != null) ? e.Attribute("transform").Value.Substring(18, 43) : null,
Upvotes: 2