- Details
- Written by: Stanko Milosev
- Category: C#
- Hits: 1307
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.
- Details
- Written by: Stanko Milosev
- Category: C#
- Hits: 1170
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.
- Details
- Written by: Stanko Milosev
- Category: C#
- Hits: 1452
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.