DEV Community

Cover image for XSD Tools in .NET8 – Part2 – C# validation
Mark Pelf
Mark Pelf

Posted on

XSD Tools in .NET8 – Part2 – C# validation

A practical guide to XSD tools available in .NET8 environment.

Abstract: A practical guide to XML and XSD tools available in .NET8 environment, focusing on generating and using C# classes to process some XML valid for some given XSD (technology as of September 2024).

1 Doing XML and XSD related work in .NET8

I was recently doing some work related to XML and XSD processing in .NET8 environment and created several proof-of-concept applications to evaluate the tools available. These articles are the result of my prototyping work.

1.1 List of tools used/tested

Here are the tools used/tested:

  • Visual Studio 2022
  • XSD.EXE (Microsoft license, part of VS2022)
  • XmlSchemaClassGenerator (Open Source/Freeware)
  • LinqToXsdCore (Open Source/Freeware)
  • Liquid XML Objects (Commercial license)

1.2 Articles in this series

For technical reasons, I will organize this text into several articles:

  • XSD Tools in .NET8 – Part1 – VS2022
  • XSD Tools in .NET8 – Part2 – C# validation
  • XSD Tools in .NET8 – Part3 – XsdExe – Simple
  • XSD Tools in .NET8 – Part4 – XsdExe - Advanced
  • XSD Tools in .NET8 – Part5 – XmlSchemaClassGenerator – Simple
  • XSD Tools in .NET8 – Part6 – XmlSchemaClassGenerator – Advanced
  • XSD Tools in .NET8 – Part7 – LinqToXsdCore – Simple
  • XSD Tools in .NET8 – Part8 – LinqToXsdCore – Advanced
  • XSD Tools in .NET8 – Part9 – LiquidXMLObjects – Simple
  • XSD Tools in .NET8 – Part10 – LiquidXMLObjects – Advanced

2 Examples of XML and XSD

Some sample XML-s and XSD-s I created for test purposes.

2.1 Simple case

<?xml version="1.0" encoding="utf-8"?>
<!--SmallCompany.xsd++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-->
<xs:schema attributeFormDefault="unqualified" 
           elementFormDefault="qualified" 
           targetNamespace="https://markpelf.com/SmallCompany.xsd" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="SmallCompany">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="CompanyName" type="xs:string" />
                <xs:element maxOccurs="unbounded" name="Employee">
                    <xs:complexType>
                        <xs:sequence>
                            <!--Name_String_NO is String NotOptional-->
                            <xs:element name="Name_String_NO" type="xs:string" />
                            <!--City_String_O is String Optional-->
                            <xs:element minOccurs="0" name="City_String_O" type="xs:string" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element maxOccurs="unbounded" name="InfoData">
                    <xs:complexType>
                        <xs:sequence>
                            <!--Id_Int_NO is Int NotOptional-->
                            <xs:element name="Id_Int_NO" type="xs:int" />
                            <!--Quantity_Int_O is Int Optional-->
                            <xs:element minOccurs="0" name="Quantity_Int_O" type="xs:int" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>
Enter fullscreen mode Exit fullscreen mode

Valid XML

<?xml version="1.0" encoding="utf-8"?>
<!--SmallCompany.xsd++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-->
<xs:schema attributeFormDefault="unqualified" 
           elementFormDefault="qualified" 
           targetNamespace="https://markpelf.com/SmallCompany.xsd" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="SmallCompany">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="CompanyName" type="xs:string" />
                <xs:element maxOccurs="unbounded" name="Employee">
                    <xs:complexType>
                        <xs:sequence>
                            <!--Name_String_NO is String NotOptional-->
                            <xs:element name="Name_String_NO" type="xs:string" />
                            <!--City_String_O is String Optional-->
                            <xs:element minOccurs="0" name="City_String_O" type="xs:string" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element maxOccurs="unbounded" name="InfoData">
                    <xs:complexType>
                        <xs:sequence>
                            <!--Id_Int_NO is Int NotOptional-->
                            <xs:element name="Id_Int_NO" type="xs:int" />
                            <!--Quantity_Int_O is Int Optional-->
                            <xs:element minOccurs="0" name="Quantity_Int_O" type="xs:int" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>
Enter fullscreen mode Exit fullscreen mode

Invalid XML

<?xml version="1.0" encoding="utf-8"?>
<!--SmallCompanyAAA.xml+++++++++++++++++++++++++++++++++++++++++++++++-->
<SmallCompany xmlns="https://markpelf.com/SmallCompany.xsd">
    <CompanyName>SmallCompanyAAA</CompanyName>
    <Employee>
        <Name_String_NO>Mark</Name_String_NO>
        <City_String_O>Belgrade</City_String_O>
    </Employee>
    <Employee>
        <Name_String_NO>John</Name_String_NO>
    </Employee>
    <InfoData>
        <Id_Int_NO>11</Id_Int_NO>
        <Quantity_Int_O>123</Quantity_Int_O>
    </InfoData>
    <InfoData>
        <Id_Int_NO>22</Id_Int_NO>
    </InfoData>
    <Offending_Element>
        Bla_Bla
    </Offending_Element>
</SmallCompany>
Enter fullscreen mode Exit fullscreen mode

2.2 Advanced case

Same as in the previous article.

3 Validation in C

Writing C# code to “validate XML for some XSD” is pretty basic, but still the right starting point.

3.1 C# code

Here is a sample code to do XML validation in C# for some XSD.

public static bool ValidateXmlForXsd(
    Microsoft.Extensions.Logging.ILogger? _logger, 
    string xmlPath, string xsdPath)
{
    bool isValid=false;

    XmlDocument xml = new XmlDocument();
    xml.Load(xmlPath);

    xml.Schemas.Add(null, xsdPath);

    try
    {
        xml.Validate(null);
        isValid = true;
    }
    catch (XmlSchemaValidationException ex)
    {
        string text1 = $"Validation FAILED for: xmlPath={xmlPath}" +
            $" and xsdPath={xsdPath} .Validation Error: " +
            ex.Message;
        _logger?.LogInformation(text1);
        isValid = false;
    }

    if (isValid)
    {
        string text1 = $"Validation SUCCESS for: xmlPath={xmlPath}" +
            $" and  xsdPath={xsdPath}";
        _logger?.LogInformation(text1);
    }
    return isValid;
}

Enter fullscreen mode Exit fullscreen mode

3.2 Success case log

Here is the log of the validation success case.

 XsdExample01-Start------------
 xmlFile11_FullPath: C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\SmallCompanyAAA.xml
 xsdFile1_FullPath: C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\SmallCompany.xsd
 xmlFile21_FullPath: C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\BigCompanyMMM.xml
 xsdFile2_FullPath: C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\BigCompany.xsd
 Validation SUCCESS for: 
 xmlPath=C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\SmallCompanyAAA.xml
 and  xsdPath=C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\SmallCompany.xsd
 Validation SUCCESS for: 
 xmlPath=C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\BigCompanyMMM.xml 
 and  xsdPath=C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\BigCompany.xsd
 XsdExample01-End------------


Enter fullscreen mode Exit fullscreen mode

3.3 Failure case log

Here is the log of the validation failure case.

 XsdExample01-Start------------
 xmlFile11_FullPath: C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\SmallCompanyAAA.xml
 xsdFile1_FullPath: C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\SmallCompany.xsd
 xmlFile21_FullPath: C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\BigCompanyMMM.xml
 xsdFile2_FullPath: C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\BigCompany.xsd
 Validation FAILED for: 
 xmlPath=C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\SmallCompanyAAA.xml 
 and xsdPath=C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\SmallCompany.xsd .
 Validation Error: The element 'SmallCompany' in namespace 'https://markpelf.com/SmallCompany.xsd' has 
 invalid child element 'Offending_Element' in namespace 'https://markpelf.com/SmallCompany.xsd'. List 
 of possible elements expected: 'InfoData' in namespace 'https://markpelf.com/SmallCompany.xsd'.
 Validation SUCCESS for: 
 xmlPath=C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\BigCompanyMMM.xml 
 and  xsdPath=C:\TmpXSD\XsdExample_Validate\Example01\bin\Debug\net8.0\XmlFiles\BigCompany.xsd
 XsdExample01-End------------
Enter fullscreen mode Exit fullscreen mode

The full example code project can be downloaded at GitHub [99].

4 References

[1] XML Schema

https://www.w3schools.com/xml/xml_schema.asp

[2] The Difference Between Optional and Not Required

https://www.infopathdev.com/blogs/greg/archive/2004/09/16/The-Difference-Between-Optional-and-Not-Required.aspx

[3] nillable and minOccurs XSD element attributes

https://stackoverflow.com/questions/1903062/nillable-and-minoccurs-xsd-element-attributes

[99] https://github.com/MarkPelf/XsdToolsInNet8

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more