Daniel Lip
Daniel Lip

Reputation: 11319

How do i check for null before applying string operation?

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

Answers (4)

Svek
Svek

Reputation: 12858

Checking for null

Transform= e.Attribute("transform")?.Value.Substring(18, 43),

credit: https://stackoverflow.com/a/44340111/3645638


Using the Sub-string.

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

Additional Information

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

Your Error

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

coolswastik
coolswastik

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

adjan
adjan

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

RJM
RJM

Reputation: 1178

You can use the ternary operator.

Transform = (e.Attribute("transform") != null) ? e.Attribute("transform").Value.Substring(18, 43) : null,

Upvotes: 2

Related Questions