如果需要对XML文件进行DTD验证,通常需要在XML文档中嵌入一个DTD声明,其中引用DTD文件的路径。但是对于我们上传到Web Server上的XML文档,通常没法让用户在他们的XML文档中指定DTD声明,因此,需要我们自己对上传上来的XML文档添加DTD声明。在这里记录一下代码。我的DTD文件是内嵌到程序集中的,因此需要首先把DTD文件从程序集中提取出来放到磁盘上,然后添加DTD声明。
1 public void VerifyXMLFile(XmlDocument doc)
2 {
3 //extract dtd file from embedded source
4 Assembly currentAssembly = Assembly.GetExecutingAssembly();
5 Stream dtdStream = currentAssembly.GetManifestResourceStream("MyProvider." + DTD_FILE_NAME);
6 string dtdPath = Path.Combine(Path.GetDirectoryName(currentAssembly.Location), DTD_FILE_NAME);
7
8 if (File.Exists(dtdPath) == false)
9 {
10 StreamReader sr = new StreamReader(dtdStream, Encoding.Default);
11 File.WriteAllText(dtdPath, sr.ReadToEnd());
12 sr.Close();
13 dtdStream.Close();
14 }
15
16 doc.InsertBefore(doc.CreateDocumentType("currencyexchange", null, dtdPath, null), doc.DocumentElement);
17 MemoryStream xmlStreamWithDTD = new MemoryStream();
18 doc.Save(xmlStreamWithDTD);
19 xmlStreamWithDTD.Position = 0;
20
21 XmlReaderSettings settings = new XmlReaderSettings();
22 settings.ProhibitDtd = false;
23 settings.ValidationType = ValidationType.DTD;
24 XmlReader reader = XmlReader.Create(xmlStreamWithDTD, settings);
25 try
26 {
27 while (reader.Read())
28 {
29 }
30 }
31 catch (Exception err)
32 {
33 throw err;
34 }
35 finally
36 {
37 reader.Close();
38 xmlStreamWithDTD.Close();
39 }
40 }
2 {
3 //extract dtd file from embedded source
4 Assembly currentAssembly = Assembly.GetExecutingAssembly();
5 Stream dtdStream = currentAssembly.GetManifestResourceStream("MyProvider." + DTD_FILE_NAME);
6 string dtdPath = Path.Combine(Path.GetDirectoryName(currentAssembly.Location), DTD_FILE_NAME);
7
8 if (File.Exists(dtdPath) == false)
9 {
10 StreamReader sr = new StreamReader(dtdStream, Encoding.Default);
11 File.WriteAllText(dtdPath, sr.ReadToEnd());
12 sr.Close();
13 dtdStream.Close();
14 }
15
16 doc.InsertBefore(doc.CreateDocumentType("currencyexchange", null, dtdPath, null), doc.DocumentElement);
17 MemoryStream xmlStreamWithDTD = new MemoryStream();
18 doc.Save(xmlStreamWithDTD);
19 xmlStreamWithDTD.Position = 0;
20
21 XmlReaderSettings settings = new XmlReaderSettings();
22 settings.ProhibitDtd = false;
23 settings.ValidationType = ValidationType.DTD;
24 XmlReader reader = XmlReader.Create(xmlStreamWithDTD, settings);
25 try
26 {
27 while (reader.Read())
28 {
29 }
30 }
31 catch (Exception err)
32 {
33 throw err;
34 }
35 finally
36 {
37 reader.Close();
38 xmlStreamWithDTD.Close();
39 }
40 }