如果存在 <!DOCTYPE html> 标记,则在 VBScript 中的 DOM XML 解析器中加载 HTML 文档会失败

Quo*_*ote 2 xml vbscript xmldom

我目前正在尝试使用 VBScript 对 HTML 文件执行批量修改。为此,我使用 Microsoft.XMLDOM 对象。无法将我的 HTML 文件作为 XML 文档加载。经过一些实验,第一行的以下标签似乎是罪魁祸首:

<!DOCTYPE html>
Run Code Online (Sandbox Code Playgroud)

如果删除此行,我的脚本将按预期工作。如果包含此行,则不会加载。不会出现任何特定的错误消息,但尝试从 XMLDOM 对象中获取任何内容都不会返回任何内容,这与对象尝试加载的文件不存在时的行为相同。

有谁知道为什么会发生这种情况以及如何解决这个问题?我无法从我的文件中删除此标签,因为它们是 HTML 文档,并且通常由另一个应用程序重新生成。

这是我的代码示例:

strFilePath = WScript.Arguments(0)
strTitlePrefix = WScript.Argument(1)

Set objXMLDoc = CreateObject("Microsoft.XMLDOM")
objXMLDoc.Async = False

objXMLDoc.load(strFilePath)

Set objDoc = objXMLDoc.documentElement
Set objNodes = objDoc.selectNodes("//title")
For Each thisNode in objNodes
  OriginalTitle = thisNode.text
  NewTitle = TitlePrefix & OriginalTitle
  thisNode.text = NewTitle     
Next
Run Code Online (Sandbox Code Playgroud)

它在这一行失败:

Set objNodes = objDoc.selectNodes("//title")
Run Code Online (Sandbox Code Playgroud)

这是错误消息:

Microsoft VBScript runtime error: Object required: 'objDoc'
Run Code Online (Sandbox Code Playgroud)

如果我删除它尝试读取的文档顶部的标记,该代码就会执行我期望的操作,因此我知道问题在于该标记导致它认为该文件不是 XML 文档。

Fra*_*nkM 6

首先,您可以通过在之后添加一些错误检查来缩小问题的原因load

objXMLDoc.load(strFilePath)
If objXMLDoc.parseError.errorCode <> 0 Then
   MsgBox "ERROR when loading " + strFileName + ": " + objXMLDoc.parseError.reason
End If
Run Code Online (Sandbox Code Playgroud)

(根据您的 VBScript 环境,您可能必须使用除 之外的其他内容MsgBox。)

您可能会收到错误消息

错误:DTD 被禁止。

!DOCTYPE原因是MSXML 6.0中默认禁止加载DTD语法(例如)。有关详细信息,请参阅MSXML 安全概述。这是相关部分

XML 的某些部分(例如 DTD 和内联模式)本质上是有风险的。在 MSXML 6.0 的默认安装配置中,这些功能已被禁用。您可以自由启用这些功能,但首先您应该确保与它们相关的安全风险不适用于您。

如果您尝试在未显式启用 ProhibitDTD 属性的情况下加载 DTD,您将收到以下错误:

错误:DTD 被禁止。

如果添加行

objXMLDoc.setProperty "ProhibitDTD", False
Run Code Online (Sandbox Code Playgroud)

加载之前,DTD is probited将不再出现该错误。

您很可能还需要添加以下行

objXMLDoc.validateOnParse = False
Run Code Online (Sandbox Code Playgroud)

加载之前,以防您的 HTML 文件不包含完整的 HTML DTD(通常不包含)。

总而言之,这是完整的代码:

strFilePath = "C:\Temp\test.html"

Set objXMLDoc = CreateObject("Msxml2.DOMDocument.6.0")
objXMLDoc.Async = False
objXMLDoc.setProperty "ProhibitDTD", False
objXMLDoc.validateOnParse = False
objXMLDoc.load(strFilePath)
If objXMLDoc.parseError.errorCode <> 0 Then
   MsgBox "ERROR when loading " + strFileName + ": " + objXMLDoc.parseError.reason
End If

Set objDoc = objXMLDoc.documentElement

MsgBox TypeName(objDoc)
Set objNodes = objDoc.selectNodes("//title")
MsgBox objNodes.Length
Run Code Online (Sandbox Code Playgroud)

它可以成功加载并解析该文件:

<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>

<body>
The content of the document......
</body>

</html> 
Run Code Online (Sandbox Code Playgroud)

最后一行将输出“1”,因为只有一个标签。

但请注意,它有一个缺点:HTML 不是 XML! 即并非每个 HTML 文件都是格式正确的 XML 文件。例如,如果在上面的示例 HTML 文件中,有一个<br>标签(没有匹配</br>),则加载将失败。使用上述方法只能打开符合 XML 的 HTML 文件。