Powershell 中 getElementById 和 getElementsByName 之间的差异

Discrepency between getElementById and getElementsByName in Powershell

我在使用 Powershell 和 MS 时遇到问题HTML:getElementById 和 getElementsByTagName 给我不同的结果。

我有这个 HTML 文件:

<html>
    <head>
        <title>Moo</title>
    </head>
    <body>
        <h1>Hello world!</h1>
        <ul id="a">
            <li>Bob
            <li>Cat
            <li>Fish
        </ul>
        <ul id="b">
            <li>Bob
            <li>Dog
            <li>Cow
        </ul>
        <div id="x">
            <b>What's the problem? Don't you <i>like soup</b> like this?</i>.
        </div>
    </body>
</html>

是的,它是故意嵌套得很糟糕的,因为我现在正在玩弄想法(并测试限制)。

我正在使用 MSHTML 将此文件加载到 Powershell 中(来自 ):

$html = new-object -ComObject "HTMLFile"
$source = get-content -path $htmlFileName -raw
$html.IHtmlDocument2_write($source)

如果我现在这样做:

$d = $html.getElementById("x")
$d.TagName

我得到了预期的输出 (DIV)。但是,如果我这样做:

$d = $html.getElementsByTagName("div")
$d[0].TagName

我没有输出。 $d.length returns 1. $d[0] | ft 吐出所有属性和值没有问题。但是直接从 $d[0] 访问属性不会 return 任何东西(即要求 innerText、outerHtml 等 return 没有数据,同时通过 ID 查找元素(即 getElementById) 没有问题,我可以访问属性。

同样,如果我分配给一个变量(即 $z = $d[0]),然后直接在 $z 上工作,我会遇到同样的问题。

我错过了什么?

问得好。

无法确切地解释发生了什么,但似乎

$d = $html.getElementsByTagName("div")

returns PowerShell 不知道如何本地操作的集合。

如果您尝试 select 部分(或全部)属性,则变量会完全填充:

($d | select *)[0].tagname

如果使用getElementsByTagName方法,你可以

$d = $html.getElementsByTagName("div") | select *
$d[0].tagname

似乎将 ComObject 传送到 Select-Object 会导致它被转换为 PowerShell PSCustomObject 然后您可以使用它:

[PS]> ($html.getelementsbytagname("div") | select *).gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PSCustomObject                           System.Object


[PS]> ($html.getelementsbytagname("div")).gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    __ComObject                              System.MarshalByRefObject

不是 100% 确定"answers"这个问题,因为我无法完全解释该行为,但这至少是一个可行的解决方法