【问题标题】:DOMDocument Method Works, XMLHTTP Method Fails - Why?DOMDocument 方法有效,XMLHTTP 方法失败 - 为什么?
【发布时间】:2014-01-13 20:21:29
【问题描述】:

设置对 Microsoft XML V6.0 的引用后,以下代码按预期工作,恢复了“buy_max”的所需值

Set xmlDoc = CreateObject("MSXML2.DOMDocument")
xmlDoc.Load ("http://api.eve-central.com/api/marketstat?typeid=24692&usesystem=30000142")

buy_max = xmlDoc.getElementsByTagName("buy")(0).getElementsByTagName("max")(0).Text

另一方面,以下代码无法恢复“buy_max”的值。而是产生错误(运行时错误 91“对象变量或未设置块变量”)。

my_url = "http://api.eve-central.com/api/marketstat?typeid=24692&usesystem=30000142"
Set html_doc = CreateObject("htmlfile")
Set xml_obj = CreateObject("MSXML2.XMLHTTP")

xml_obj.Open "GET", my_url, False
xml_obj.send
html_doc.body.innerhtml = xml_obj.ResponseText

buy_max = html_doc.getElementsByTagName("buy")(0).getElementsByTagName("max")(0).innertext

谁能解释为什么第二种方法会失败? TIA,罗恩

【问题讨论】:

  • 您在哪一行得到异常?
  • 当我尝试执行“buy_max = html_doc.getElementsByTagName...”行时

标签: xml vba excel getelementsbytagname


【解决方案1】:

好吧,我无法解释,但我可以给你一些信息。我运行了你的代码,进入即时窗口并输入

?left(html_doc.body.innerHTML,50)
62</VOLUME><AVG>187369914.11</AVG><MAX>191103298.9

奇怪的是它会在第一个 VOLUME 的结束标记之后开始。所以我查看了ResponseText

?left(xml_obj.responseText,50)
<?xml version='1.0' encoding='utf-8'?>
<evec_api v

从正确的地方开始。作为 MSHTML 一部分的 HTML 解析器正在做一些意想不到的事情。但我肯定无法弄清楚它为什么会这样做。我认为引号有些问题-就像它们不是真正的引号一样。所以我复制了 xml 并粘贴到记事本中,认为会显示非标准字符或转换它们。我保存了文本文件,将其读入 html 文档并出现完全相同的错误。

然后我开始将越来越少的 xml 文件复制到记事本中 - 一样。我开始抄袭了

<volume>62</volume>

并返回 html_doc.body.innertext

62</volume>

所以我只复制了

<avg>187369914.11</avg>

并返回 html_doc.body.innertext

187369914.11</avg>

最后,我把这个放在文档里

<p><volume>62</volume></p>

hmtl_doc.body.innerhtml 返回

<P>
<P>62</VOLUME></P>
<P></P>

然后我放弃了。抱歉,这不是一个很好的答案,但希望其他人可以加入。

【讨论】:

    【解决方案2】:

    为什么会失败:

    第一个.getelementsbytagname("buy")(0) 调用返回一个空对象。第二个 .getelementsbytagname 调用是针对空对象的,将导致错误 91。

    奇怪的一点是ResponseText 被隐式地分成innerhtmlouterhtml(即使你使用了.innerhtml = ...

    我建议选择一个存在于您的innerhtml 中的标签;假设我们选择“min”。如果你尝试Set buy_max = html_doc.getElementsByTagName("min")(0) 然后检查这个对象,你会看到新对象innerhtmlcontent 恢复到它本来应该是的状态(在html_doc 内);但即便如此,任何其他.getelementsbytagname 调用都将返回一个空对象。

    帮助调试:

    单击Views --&gt; Locals Window 以帮助可视化对象的内容以及可供您使用的变量。您需要在对象初始化并设置好值后设置断点。

    请问:

    为什么第一个解决方案(已经有效)不够好?

    我会补充:

    如果您只是在寻找第一个解决方案的替代方案,请查看此处:HtmlDocument Class Resource (MSDN)

    【讨论】:

    • 感谢伯纳德的洞察力。第一个解决方案很好,我只是想了解为什么第二种方法不起作用。看起来页面背后的源代码有点奇怪。
    • 如果我的回答让您满意,请将问题标记为已回答 :)
    • 我真的很想有人解释为什么源代码行为异常
    【解决方案3】:

    什么对我有用

    看来"HTMLFile" 实例只能在Open 方法完成某种初始化后才能使用。

    VBScript:

    Set html_doc = CreateObject("htmlfile")
    html_doc.Open
    ' whatever you have to do
    html_doc.Close
    

    JavaScript:

    var html_doc = new ActiveXObject("htmlfile");
    html_doc.open();
    // whatever you have to do
    html_doc.close();
    

    如果Open方法没有被调用怎么办

    根据我的经验,如果你不调用Open 方法,那么就无法使用对象的某些方法和属性,而其他属性和方法则正常运行。这很令人困惑,因为没有消息、错误或任何说明该做什么的内容。

    • write 文档的方法不执行任何操作或抛出
    • body 文档的属性为空
    • innerHTML 任何元素的属性在读取时为空,在写入时抛出
    • createElement 文档的方法有效
    • tagName 任何元素的属性都有效

    【讨论】:

      猜你喜欢
      • 2022-01-16
      • 1970-01-01
      • 2014-01-24
      • 2020-10-25
      • 1970-01-01
      • 2011-12-15
      • 2014-05-16
      • 1970-01-01
      相关资源
      最近更新 更多