I'm creating blazor webassembly project to extract data from a XML file and display that data in a grid. users can edit that data using the UI interface. when the user edits that data and clicks on the submit button I want to validate the changes that user did, with a XSD file. not the whole XML file, only the specific part of XML file needs to be validated.
In the project, there is a validationservice class. in that class, there is a method called validate, and it takes a deserialized XML object as a parameter. this will validate the whole XML file with the XSD file. How Can I validate the specific part of the XML file?
using AEOIToolWebApp.Client.Common.Interfaces;
using AEOIToolWebApp.Client.Common.Services;
using AEOIToolWebApp.Shared;
namespace AEOIToolWebApp.Client.State
{
public class XMLDataState
{
public readonly HttpClient _httpClient;
public readonly ValidationService _validationService;
public readonly ILogger _logger;
public readonly IXMLDataAPIService _xmlDataAPIService;
public List<ReportResult> ReportResults { get; set; } = new();
public string FileName { get; set; } = "AEOI_ v2.0_Example_New_Submission 1.xml";
public List<FinancialInstitutionsInstitution> Institutes { get; set; }
public XMLSummary[] XMLSummaryList { get; set; }
public List<XMLSummary> validationResults { get; set; } = new();
public XMLDataState(HttpClient httpClient, ValidationService validationService, ILogger<XMLDataAPIService> logger, IXMLDataAPIService xmlDataApiService)
{
_httpClient = httpClient;
_validationService = validationService;
_logger = logger;
_xmlDataAPIService = xmlDataApiService;
}
public async Task onInit()
{
Console.WriteLine("starting onInit in xmldatastate");
var data = await _xmlDataAPIService.GetXMLData();
Institutes = new List<FinancialInstitutionsInstitution>(data.Items);
validationResults = new();
validationResults = await _validationService.validate(data);
XMLSummaryList = validationResults.ToArray();
ReportResults = new();
foreach (var item in Institutes)
{
ReportResults.Add(new ReportResult
{
Id = item.id,
AddressField = item.Address,
ContactField = item.Contact,
DetailsField = item.Details,
IdentificationNumberField = item.IdentificationNumber,
OptionsField = item.Options,
XMLSummary = validationResults.Where(x => x.Id == item.id).ToList(),
ErrorCount = validationResults.Where(x => x.Id == item.id).Count(),
WarnningCount = validationResults.Where(x => x.Id == item.id).Count()
});
}
}
}
}
ValidationService class
public class ValidationService
{
private readonly HttpClient client;
private readonly ILogger<ValidationService> logger;
private List<string> result = new List<string>();
private XmlSchema typesSchema;
private XmlSchema schema;
private int count = 0;
public List<XMLSummary> XMLSummaryList { get; set; } = new();
public string CurrentNode { get; set; } = "";
public string CurrentFIId { get; set; }
//test
private XmlSchema xmlSchemaForFinancialInstitution;
public ValidationService(HttpClient client, ILogger<ValidationService> logger)
{
this.client = client;
this.logger = logger;
}
private void SchemaValidationHandler(object sender, ValidationEventArgs e)
{
logger.LogInformation(e.Message);
}
private void DocumentValidationHandler(object sender, ValidationEventArgs e)
{
logger.LogInformation(e.Message);
}
public XmlDocument SerializeToXml<T>(T source)
{
var document = new XmlDocument();
var navigator = document.CreateNavigator();
using (var writer = navigator.AppendChild())
{
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer, source);
}
return document;
}
private async Task LoadSchemanote()
{
var typesStream = await client.GetStreamAsync("Templates/Books.xsd");
}
public async Task<List<XMLSummary>> validate(FinancialInstitutions financialInstitution)
{
XMLSummaryList = new();
Console.WriteLine($"w {financialInstitution.Items.Count()}");
var financialInstitutionSchema = await client.GetStreamAsync("Templates/FinancialInstitutions.xsd");
xmlSchemaForFinancialInstitution = XmlSchema.Read(financialInstitutionSchema, SchemaValidationHandler);
XmlReaderSettings financialInstitutionSettings = new XmlReaderSettings();
financialInstitutionSettings.Schemas.Add(xmlSchemaForFinancialInstitution);
financialInstitutionSettings.ValidationType = ValidationType.Schema;
financialInstitutionSettings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
financialInstitutionSettings.ValidationEventHandler += new ValidationEventHandler(booksSettingsValidationEventHandler);
var document = new XmlDocument();
document = SerializeToXml(financialInstitution);
XmlReader xmlReader = new XmlNodeReader(document);
var bookstream = await client.GetStreamAsync("Templates/FinancialInstitutions.xml");
using (XmlReader books = XmlReader.Create(bookstream,financialInstitutionSettings))
{
while (books.Read())
{
if (books.LocalName != "")
{
CurrentNode = books.LocalName;
}
if (books.LocalName.Equals("Institution") && books.AttributeCount > 0)
{
CurrentFIId = books.GetAttribute(0);
count++;
}
}
}
return XMLSummaryList;
}
void booksSettingsValidationEventHandler(object sender, ValidationEventArgs e)
{
XMLSummary errorInfo = new XMLSummary { Row = count, Errors = e.Message,Id=CurrentFIId };
XMLSummaryList.Add(errorInfo);
if (e.Severity == XmlSeverityType.Warning)
{
Console.Write($"Warning: {e.Message} ");
}
else if (e.Severity == XmlSeverityType.Error)
{
}
}
}
XML File
<?xml version="1.0" encoding="UTF-8"?>
<FinancialInstitutions xmlns="https://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.w3schools.com/xml FinancialInstitutions.xsd">
<Institution id="1">
<Details>
<Reference>reference 1</Reference>
<Name>SBC 1</Name>
<Type>type 1</Type>
<TaxResidency>CAYMAN ISLANDS</TaxResidency>
</Details>
<IdentificationNumber>
<AccountId>1000000</AccountId>
<TaxIdentificationNumber>FI123456</TaxIdentificationNumber>
</IdentificationNumber>
<Address>
<BuildingNumber>123</BuildingNumber>
<StreetName>Any Street</StreetName>
<District>district 1</District>
<City>George Town</City>
<PostCode>01010</PostCode>
<Country>country 1</Country>
</Address>
<Contact>
<FirstName>John</FirstName>
<LastName>smith</LastName>
<Email>[email protected]</Email>
<TelephoneNumber>071785689</TelephoneNumber>
</Contact>
<Options>
<OriginalDocRefID>1452</OriginalDocRefID>
<Label>label 1</Label>
</Options>
</Institution>
<Institution id="2">
<Details>
<Reference>reference 2</Reference>
<Name>SBC 2</Name>
<Type>type 1</Type>
<TaxResidency>CAYMAN ISLANDS</TaxResidency>
</Details>
<IdentificationNumber>
<AccountId>21000000</AccountId>
<TaxIdentificationNumber>FI123457</TaxIdentificationNumber>
</IdentificationNumber>
<Address>
<BuildingNumber>456</BuildingNumber>
<StreetName>Any Street</StreetName>
<District>district 1</District>
<City>George Town</City>
<PostCode>02020</PostCode>
<Country>country 1</Country>
</Address>
<Contact>
<FirstName>mitchell</FirstName>
<LastName>marsh</LastName>
<Email>[email protected]</Email>
<TelephoneNumber>1785682</TelephoneNumber>
</Contact>
<Options>
<OriginalDocRefID>1453</OriginalDocRefID>
<Label>label 2</Label>
</Options>
</Institution>
</FinancialInstitutions>
XSD file
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="FinancialInstitutions" targetNamespace="https://www.w3schools.com" xmlns:mstns="https://www.w3schools.com" xmlns="https://www.w3schools.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:element name="FinancialInstitutions" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Institution">
<xs:complexType>
<xs:sequence>
<xs:element name="Details" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="Reference" type="xs:string" minOccurs="0" />
<xs:element name="Name" type="xs:integer" minOccurs="0" />
<xs:element name="Type" type="xs:integer" minOccurs="0" />
<xs:element name="TaxResidency" type="xs:integer" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="IdentificationNumber" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="AccountId" type="xs:string" minOccurs="0" />
<xs:element name="TaxIdentificationNumber" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Address" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="BuildingNumber" type="xs:string" minOccurs="0" />
<xs:element name="StreetName" type="xs:string" minOccurs="0" />
<xs:element name="District" type="xs:string" minOccurs="0" />
<xs:element name="City" type="xs:string" minOccurs="0" />
<xs:element name="PostCode" type="xs:string" minOccurs="0" />
<xs:element name="Country" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Contact" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="FirstName" type="xs:string" minOccurs="0" />
<xs:element name="LastName" type="xs:string" minOccurs="0" />
<xs:element name="Email" type="xs:string" minOccurs="0" />
<xs:element name="TelephoneNumber" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Options" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="OriginalDocRefID" type="xs:string" minOccurs="0" />
<xs:element name="Label" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" form="unqualified" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
Let's say the user edit detail of the second Institution. In that case I want to validate only that section without validating the whole file