milosev.com
  • Home
    • List all categories
    • Sitemap
  • Downloads
    • WebSphere
    • Hitachi902
    • Hospital
    • Kryptonite
    • OCR
    • APK
  • About me
    • Gallery
      • Italy2022
      • Côte d'Azur 2024
    • Curriculum vitae
      • Resume
      • Lebenslauf
    • Social networks
      • Facebook
      • Twitter
      • LinkedIn
      • Xing
      • GitHub
      • Google Maps
      • Sports tracker
    • Adventures planning
  1. You are here:  
  2. Home

Validating XML with XSL

Details
Written by: Stanko Milosev
Category: C#
Published: 11 October 2024
Last Updated: 19 November 2024
Hits: 1210
  • xml
  • xslt 2.0
First install Saxon-HE, it looks like that it Saxon Home Edition does not support .NET core, which is why test project has to be .NET Framework.

Example method:

private static string ValidateXmlFile(string inputFile, string transformFile)
{
	try
	{
		if (string.IsNullOrWhiteSpace(inputFile))
		{
			throw new FileNotFoundException("Filename is empty");
		}

		inputFile = Path.GetFullPath(inputFile);
		if (!File.Exists(inputFile))
		{
			throw new FileNotFoundException($"File: {inputFile} not found");
		}

		transformFile = Path.GetFullPath(transformFile);
		if (!File.Exists(transformFile))
		{
			throw new FileNotFoundException($"File: {transformFile} not found");
		}

		Processor processor = new Processor();

		DocumentBuilder builder = processor.NewDocumentBuilder();
		builder.BaseUri = new Uri(inputFile);

		XdmNode inputNode;
		using (var inputStream = File.OpenRead(inputFile))
		{
			inputNode = builder.Build(inputStream);
		}

		XsltCompiler compiler = processor.NewXsltCompiler();
		XsltExecutable executable;
		using (var xsltStream = File.OpenRead(transformFile))
		{
			executable = compiler.Compile(xsltStream);
			if (compiler.GetErrorList().Count != 0)
				throw new Exception("Exception loading xsl!");
		}

		XsltTransformer transformer = executable.Load();

		transformer.InitialContextNode = inputNode;

		Serializer serializer = processor.NewSerializer();
		using (var stringWriter = new StringWriter())
		{
			serializer.SetOutputWriter(stringWriter);
			transformer.Run(serializer);
			string result = stringWriter.ToString();
			return result;
		}
	}
	catch (Exception e)
	{
	   return e.Message;
	}
}
Since validation result is XML, we can parse failed validations like:
IEnumerable<FailedAssert> failedAsserts = doc.Descendants(svrl + "failed-assert")
	.Select(fa => new FailedAssert
	{
		Flag = fa.Attribute("flag")?.Value,
		Id = fa.Attribute("id")?.Value,
		Test = fa.Attribute("test")?.Value,
		Location = fa.Attribute("location")?.Value,
		Text = fa.Element(svrl + "text")?.Value
	});
SVRL is an abbreviation for 'Schematron Validation Report Language.'

FailedAssert class looks like:

public class FailedAssert
{
	public string Flag { get; set; }
	public string Id { get; set; }
	public string Test { get; set; }
	public string Location { get; set; }
	public string ExceptionMessage { get; set; }
	public string Text { get; set; }
}
Example download from here. For this example I used file 01.03a-INVOICE_uncefact.xml which I downloaded from here where I manipulated with DateTimeField. Instead of a date I wrote "test", in order to trigger a failed assertion. I also downloaded XSL file EN16931-CII-validation.xsl from "Koordinierungsstelle für IT-Standards" (KoSIT) GitHub repository.

Master - Detail with DataGridView and DataTables example

Details
Written by: Stanko Milosev
Category: C#
Published: 11 October 2024
Last Updated: 19 November 2024
Hits: 1107
Here, I gave one example of in-memory DataTables master - detail relationship.

Now I will extend that example with DataGridView.

First lets create master DataTable:

private DataTable CreateMasterDataTable()
{
	DataTable dtMaster = new DataTable("Master");
	dtMaster.Columns.Add("Id", typeof(int));
	dtMaster.Columns.Add("SomeText", typeof(string));
	dtMaster.PrimaryKey =
	[
		dtMaster.Columns["Id"]
	];

	return dtMaster;
}
Now detail DataTable:
private DataTable CreateDetailDataTable()
{
	DataTable dtDetail = new DataTable("Detail");
	dtDetail.Columns.Add("Id", typeof(int));
	dtDetail.Columns.Add("MasterId", typeof(int));
	dtDetail.Columns.Add("SomeText", typeof(string));
	dtDetail.PrimaryKey =
	[
		dtDetail.Columns["Id"]
		, dtDetail.Columns["MasterId"]
	];

	return dtDetail;
}
DataSet:
DataSet dsMasterDetail = new DataSet("MasterDetail");
dsMasterDetail.Tables.Add(CreateMasterDataTable());
dsMasterDetail.Tables.Add(CreateDetailDataTable());
Relation and add relation to DataSet:
DataRelation relMasterDetail = new DataRelation("MasterDetailRelation"
	, dsMasterDetail.Tables["Master"].Columns["Id"]
	, dsMasterDetail.Tables["Detail"].Columns["MasterId"]
);

dsMasterDetail.Relations.Add(relMasterDetail);
Now, lets create BindingSource and attach it to DataSource of DataGridView:
var dsMasterDetail = CreateMasterDetailDataSet();
BindingSource bsMaster = new BindingSource
{
	DataSource = dsMasterDetail,
	DataMember = "Master"
};
dgvMaster.DataSource = bsMaster;

BindingSource bsDetail = new BindingSource
{
	DataSource = bsMaster,
	DataMember = "MasterDetailRelation"
};
dgvDetail.DataSource = bsDetail;
Here notice that DataSource of detail BindingSource I have attached master BindingSource, as DataMember name of relation:
BindingSource bsDetail = new BindingSource
{
	DataSource = bsMaster,
	DataMember = "MasterDetailRelation"
};
Example download from here.

Simple MVVM example in Windows Forms

Details
Written by: Stanko Milosev
Category: C#
Published: 20 May 2024
Last Updated: 20 May 2024
Hits: 1394
This is my simplified example of Klaus Loeffelmann article. With my example will just execute MessageBox.Show("Hello world");

First I have started new WinForms with .NET 8.0 support, and installed nuGet package CommunityToolkit.Mvvm, then I have added new button, and the class SimpleCommandViewModel which inherits INotifyPropertyChanged:

public class SimpleCommandViewModel: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

    private RelayCommand _sampleCommand;

    public SimpleCommandViewModel()
    {
        _sampleCommand = new RelayCommand(ExecuteSampleCommand);
    }

    public void ExecuteSampleCommand()
        => MessageBox.Show("Hello world");

    public RelayCommand SampleCommand
    {
        get => _sampleCommand;
        set
        {
            if (_sampleCommand == value)
            {
                return;
            }

            _sampleCommand = value;
            OnPropertyChanged();
        }
    }
}
Here notice:
new RelayCommand(ExecuteSampleCommand);
That means that by default my button is enabled, in comparsion of Klaus Loeffelmann article:
new RelayCommand(ExecuteSampleCommand, CanExecuteSampleCommand);
Where his button will enabled only if CanExecuteSampleCommand is set to true.

Now, build it at least once.

Then in Properties -> DataBindings -> Command -> add new Object DataSource -> choose SimpleCommandViewModel, after choose SampleCommand from dropdown list. In Form Load event add code:

private void Form1_Load(object sender, EventArgs e)
{
	simpleCommandViewModelBindingSource.DataSource = new SimpleCommandViewModel();
}
Example download from here.

Post image and additional data to WebAPI

Details
Written by: Stanko Milosev
Category: C#
Published: 14 March 2024
Last Updated: 14 March 2024
Hits: 5506

According to https://stackoverflow.com/a/14413414

Natively WebAPI doesn't support binding of multiple POST parameters. 

Here I already gave two examples of WebAPI with multiple Post parameters. Now I will use similiar approach to send image plus additional data, like file and folder name.

First don't forget in Program.cs to add Service:

builder.Services.AddMvc().AddNewtonsoftJson();

Controller:

using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;

namespace UploadImageServer.Controllers;

public class UploadImageController : Controller
{
    [HttpPost]
    [Route("UploadImage")]

    public async Task<IActionResult> UploadImage([FromBody] JObject? data)
    {
        if (data is null) return BadRequest(new { message = "No image." });
        string? base64Image = data["image"]?.ToString();

        if (base64Image == null) return BadRequest(new { message = "No image." });
        byte[] imageBytes = Convert.FromBase64String(base64Image);

        Directory.CreateDirectory(data["folderName"]?.ToString() ?? string.Empty);

        string imagePath = $"{data["folderName"]}\\{data["fileName"]}";
        await System.IO.File.WriteAllBytesAsync(imagePath, imageBytes);

        return Ok(new { message = "Image uploaded successfully." });
    }
}
Server download from here.

---

Client:

using Newtonsoft.Json.Linq;
using System.Net.Http.Headers;

string imageUrl = "spring.jpg";
string base64Image = ConvertImageToBase64(imageUrl);
var jsonData = new JObject
{
    ["image"] = base64Image
    , ["fileName"] = "magnolia.jpg"
    , ["folderName"] = "spring"
};
string jsonContent = jsonData.ToString();

using HttpClient client = new HttpClient();
StringContent content = new StringContent(jsonContent);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

HttpResponseMessage response = await client.PostAsync("https://localhost:7028/UploadImage", content);

if (response.IsSuccessStatusCode)
{
    Console.WriteLine("Image uploaded successfully!");
}
else
{
    Console.WriteLine("Failed to upload image. Status code: " + response.StatusCode);
}

static string ConvertImageToBase64(string imagePath)
{
    byte[] imageBytes = File.ReadAllBytes(imagePath);
    return Convert.ToBase64String(imageBytes);
}
Client download from here.
  1. FluentFTP async example
  2. log4net example
  3. Two examples of WebAPI with multiple Post parameters
  4. HttpClient Get and Post

Subcategories

C#

Azure

ASP.NET

JavaScript

Software Development Philosophy

MS SQL

IBM WebSphere MQ

MySQL

Joomla

Delphi

PHP

Windows

Life

Lazarus

Downloads

Android

CSS

Chrome

HTML

Linux

Eclipse

Page 5 of 166

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10