Validate only a part of XML file using an XSD and display errors

124 views Asked by At

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

0

There are 0 answers