Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# read XML with DTD verification

Tags:

c#

xml

dtd

I'm trying to read an XML file with dtd verification but no mather how I do it seems like the program doesn't read my dtd file. I have concentrated the problem to a small xml file and a small dtd file:

test.xml - Located at c:\test.xml

<?xml version="1.0"?>
<!DOCTYPE Product SYSTEM "test.dtd">
<Product ProductID="123">
   <ProductName>Rugby jersey</ProductName>
</Product>

test.dtd - located at c:\test.dtd

<!ELEMENT Product (ProductName)>
<!ATTLIST Product ProductID CDATA #REQUIRED>
<!ELEMENT ProductName (#PCDATA)>

My C# program looks like this

namespace XML_to_csv_converter
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ReadXMLwithDTD();
        }

        public void ReadXMLwithDTD()
        {
            // Set the validation settings.
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ValidationType = ValidationType.DTD;
            settings.DtdProcessing = DtdProcessing.Parse;
            settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
            settings.IgnoreWhitespace = true;

            // Create the XmlReader object.
            XmlReader reader = XmlReader.Create("c:/test.xml", settings);

            // Parse the file.
            while (reader.Read())
            {
                System.Console.WriteLine("{0}, {1}: {2} ", reader.NodeType, reader.Name, reader.Value);
            }
        }

        private static void ValidationCallBack(object sender, ValidationEventArgs e)
        {
            if (e.Severity == XmlSeverityType.Warning)
                Console.WriteLine("Warning: Matching schema not found.  No validation occurred." + e.Message);
            else // Error
                Console.WriteLine("Validation error: " + e.Message);
        }
    }
}

This results in the output:

XmlDeclaration, xml: version="1.0" 
DocumentType, Product:  
Validation error: The 'Product' element is not declared.
Element, Product:  
Validation error: The 'ProductName' element is not declared.
Element, ProductName:  
Text, : Rugby jersey 
EndElement, ProductName:  
EndElement, Product: 

I have tried to have the files in defferent locations and i have tried both relative and absolute paths. I have tried to copy an example from microsoft webpage and it resulted in the same problem. Someone have an idea of what can be the problem? Is there any way to see if the program was able to load the dtd file?

like image 510
Daniel Falk Avatar asked Dec 19 '22 00:12

Daniel Falk


2 Answers

I cannot comment so I add an answer to the correct answer by Jim :

// SET THE RESOLVER
settings.XmlResolver = new XmlUrlResolver();

this is a breaking change between .Net 4.5.1 and Net 4.5.2 / .Net 4.6. The resolver was set by default to XmlUrlResolver before. Got stung by this.

like image 195
Michel de Becdelièvre Avatar answered Dec 28 '22 23:12

Michel de Becdelièvre


You need to add the resolver.

XmlReaderSettings settings = new XmlReaderSettings();

// SET THE RESOLVER
settings.XmlResolver = new XmlUrlResolver();

settings.ValidationType = ValidationType.DTD;
settings.DtdProcessing = DtdProcessing.Parse;
settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
settings.IgnoreWhitespace = true;

As long as the two files are in the same directory, this will work. Alternatively you need to provide an URL to the DTD.

XmlUrlResolver can also be overridden to provide additional semantics to the resolution process.

like image 33
Jim Avatar answered Dec 28 '22 23:12

Jim