【问题标题】:Validate XML against DTD - expected markup not found根据 DTD 验证 XML - 未找到预期的标记
【发布时间】:2018-07-30 18:00:24
【问题描述】:

我知道这里有类似的问题。不幸的是,我找不到任何可以为我提供答案的东西。 我正在尝试针对现有的 DTD 文件验证 XML,但我的代码一直在抛出

未找到预期的 DTD 标记。第 1 行位置 1。

这就是 XML 的样子(只有头部,缩写):

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE tms PUBLIC "-//Schema//DTD DocuMan TMS V5//EN" "Tms.dtd"[]>
<tms name=...

这是引用的 DTD 的样子(开头注释版权,省略,为便于阅读而缩写):

<!ENTITY % para 'p|codeblock|procedural-instructions'>
<!ENTITY % list '(ul|ol)'>
...
...
<!-- simple reference to original dtd -->
<!ENTITY % ST4.dtd SYSTEM "ST4.dtd">
%ST4.dtd;
...
...
<!ELEMENT tms (tmsnode|node|rtf)*>
<!ATTLIST tms
...
...

引用的第二个 DTD 如下所示:

<!ENTITY lt    "&#38;#60;"> <!-- < -->
<!ENTITY gt    "&#38;#62;"> <!-- > -->
<!ENTITY amp   "&#38;#38;"> <!-- & -->
...
...
<!ELEMENT comment (#PCDATA| br | tab)*>
...
...

如果您想知道的话,所有 DTD 都没有额外的“DOCTYPE”元素。

这是我根据 DTD 读取/验证 XML 文件的代码:

var xml = new XmlDocument();
try
{
    xml.Load(fil);
    var settings = new XmlReaderSettings
    {
        DtdProcessing = DtdProcessing.Parse,
        ValidationType = ValidationType.DTD,
        XmlResolver = new XmlUrlResolver()
    };
    var context = new XmlParserContext(xml.NameTable,
        new XmlNamespaceManager(xml.NameTable),
        xml.DocumentType.Name, "", xml.DocumentType.PublicId, xml.DocumentType.SystemId, "", "en", XmlSpace.Default);
    using (var reader = XmlReader.Create(fil, settings, context))
    {
        try
        {
            while (reader.Read()){}
        }
        catch (Exception except)
        {
            bkwValidate.ReportProgress(index, Path.GetFileName(fil) + ": " + except.Message);
        }
    }
}
catch (Exception exception)
{
    bkwValidate.ReportProgress(index, Path.GetFileName(fil) + ": " + exception.Message);
}

更新

事实证明,我为此搜索的代码中有一个错误:XmlParserContext 的参数顺序不正确。 internalSubset 的空字符串需要在 sysId 之后。现在这让我更进一步:

var context = new XmlParserContext(xml.NameTable,
    new XmlNamespaceManager(xml.NameTable),
    xml.DocumentType.Name,xml.DocumentType.PublicId, xml.DocumentType.SystemId, "","", "en", XmlSpace.Default);

不幸的是,我现在遇到了一个错误

不能有多个 DTD

【问题讨论】:

  • 我想我可能找到了一些东西。如果我对上下文使用不同的重载,则错误将更改为“不能有多个 DTD”,这将我带到了那里:这里:stackoverflow.com/questions/22516221/…。会试试这个。

标签: c# xmlreader dtd xml


【解决方案1】:

Heureka!

问题在于 XmlParserContext:它太详细了!

如果我只考虑最基本的需求,即使有多个 DTD,这也可以正常工作:

var xml = new XmlDocument();
try
{
    xml.Load(fil);
    var settings = new XmlReaderSettings
    {
        DtdProcessing = DtdProcessing.Parse,
        ValidationType = ValidationType.DTD,
        XmlResolver = new XmlUrlResolver(),
        NameTable = xml.NameTable
    };

    var context = new XmlParserContext(xml.NameTable, new XmlNamespaceManager(xml.NameTable), "en",
        XmlSpace.Preserve);

    using (var reader = XmlReader.Create(fil, settings, context))
    {
        try
        {
            while (reader.Read()) { }
        }
        catch (Exception except)
        {
            bkwValidate.ReportProgress(index, Path.GetFileName(fil) + ": " + except.Message);
        }
    }
}
catch (Exception exception)
{
    bkwValidate.ReportProgress(index, Path.GetFileName(fil) + ": " + exception.Message);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 2015-12-24
    • 1970-01-01
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    相关资源
    最近更新 更多