C# .NET:如何在没有 DOCTYPE 声明的情况下使用 DTD 验证 XML 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/470313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 04:40:54  来源:igfitidea点击:

.NET : How to validate XML file with DTD without DOCTYPE declaration

c#.netxmlvb.netdtd

提问by Vincent

I have an XML file with no DOCTYPE declaration that I would like to validate with an external DTD upon reading.

我有一个没有 DOCTYPE 声明的 XML 文件,我想在阅读时使用外部 DTD 进行验证。

Dim x_set As Xml.XmlReaderSettings = New Xml.XmlReaderSettings()
x_set.XmlResolver = Nothing
x_set.CheckCharacters = False
x_set.ProhibitDtd = False
x = XmlTextReader.Create(sChemin, x_set)

How do you set the path for that external DTD? How do you validate?

您如何设置该外部 DTD 的路径?你如何验证?

回答by Jim Counts

Could you create an Xml.XmlDocument with the DTD you want, then append the XML file data to the in-memory Xml.XmlDocument, then validate that?

您能否使用您想要的 DTD 创建一个 Xml.XmlDocument,然后将 XML 文件数据附加到内存中的 Xml.XmlDocument,然后进行验证?

回答by bstoney

I have used the following function successfully before, which should be easy to adapt. How ever this relies on creating a XmlDocument as magnifico mentioned. This can be achieved by:

我之前成功使用过以下功能,应该很容易适应。这如何依赖于创建 magnifico 提到的 XmlDocument。这可以通过以下方式实现:

XmlDocument doc = new XmlDocument();
doc.Load( filename );
doc.InsertBefore( doc.CreateDocumentType( "doc_type_name", null, DtdFilePath, null ), 
    doc.DocumentElement );


/// <summary>
/// Class to test a document against DTD
/// </summary>
/// <param name="doc">XML The document to validate</param>
private static bool ValidateDoc( XmlDocument doc )
{
    bool isXmlValid = true;
    StringBuilder xmlValMsg = new StringBuilder();

    StringWriter sw = new StringWriter();
    doc.Save( sw );
    doc.Save( TestFilename );

    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ProhibitDtd = false;
    settings.ValidationType = ValidationType.DTD;
    settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings;
    settings.ValidationEventHandler += new ValidationEventHandler( delegate( object sender, ValidationEventArgs args )
    {
        isXmlValid = false;
        xmlValMsg.AppendLine( args.Message );
    } );

    XmlReader validator = XmlReader.Create( new StringReader( sw.ToString() ), settings );

    while( validator.Read() )
    {
    }
    validator.Close();

    string message = xmlValMsg.ToString();
    return isXmlValid;
}

回答by Matt

private static bool _isValid = true;
static void Main(string[] args)
{
    using (MemoryStream ms = new MemoryStream())
    {
        using (FileStream file = new FileStream("C:\MyFolder\Product.dtd", FileMode.Open, FileAccess.Read))
        {
            byte[] bytes = new byte[file.Length];
            file.Read(bytes, 0, (int) file.Length);
            ms.Write(bytes, 0, (int) file.Length);
        }
        using (FileStream file = new FileStream("C:\MyFolder\Product.xml", FileMode.Open, FileAccess.Read))
        {
            byte[] bytes = new byte[file.Length];
            file.Read(bytes, 0, (int) file.Length);
            ms.Write(bytes, 0, (int) file.Length);
        }
        ms.Position = 0;

        var settings = new XmlReaderSettings();
        settings.DtdProcessing = DtdProcessing.Parse;
        settings.ValidationType = ValidationType.DTD;
        settings.ValidationEventHandler += new ValidationEventHandler(OnValidationEvent);
        var reader = XmlReader.Create(ms, settings);

        // Parse the file.  
        while (reader.Read()) ;
    }
    // Check whether the document is valid or invalid.
    if (_isValid)
        Console.WriteLine("Document is valid");
    else
        Console.WriteLine("Document is invalid");
}

private static void OnValidationEvent(object obj, ValidationEventArgs args)
{
    _isValid = false;
    Console.WriteLine("Validation event\n" + args.Message);
}