【发布时间】:2012-04-27 17:58:40
【问题描述】:
我正在使用字符串设置 XML 属性,PowerShell 告诉我“只有字符串可以用作设置 XmlNode 属性的值”。这是一个简单的例子。首先,我运行这个:
$xmlDoc = [xml]@"
<root>
<ComponentRef Id="a" />
</root>
"@
$newId = "b"
$length = $newId.Length
Write-Host ("`n`$newId is a string, see: `$newId.GetType().FullName = " + $newId.GetType().FullName + "`n")
Write-Host ("Running `"`$xmlDoc.root.ComponentRef.Id = `$newId`"...`n")
$xmlDoc.root.ComponentRef.Id = $newId
Write-Host ("ComponentRef.Id is now: " + $xmlDoc.root.ComponentRef.Id)
对我来说,输出是:
$newId is a string, see: $newId.GetType().FullName = System.String
Running "$xmlDoc.root.ComponentRef.Id = $newId"...
Cannot set "Id" because only strings can be used as values to set XmlNode properties.
At D:\Build\Tools\mass processing\Untitled4.ps1:14 char:27
+ $xmlDoc.root.ComponentRef. <<<< Id = $newId
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
ComponentRef.Id is now: a
该错误消息一定是错误的。等号右侧的值是一个字符串,如上面的输出所示。但它出错了,所以 XML 属性仍然读取“a”。现在它变得更奇怪了。让我们将调用 $newId.length 的行注释掉,然后观察它是否正常工作。
这样注释掉:#$length = $newId.Length。现在的输出是:
$newId is a string, see: $newId.GetType().FullName = System.String
Running "$xmlDoc.root.ComponentRef.Id = $newId"...
ComponentRef.Id is now: b
我不是要求修复,因为我知道如何通过转换为最后一个赋值运算符右侧的 [string] 来解决此问题。我想知道的是:
谁能解释为什么调用 $newId.Length(一个 getter!)会导致 PowerShell 认为 $newId 不再是一个字符串?
谢谢!
【问题讨论】:
-
似乎问题出在如何从根 .NET 对象改编 PowerShell 对象(例如,在 C# 中您不能调用 xmlDoc.root - root 是 PS 添加的属性) .这对 PS 和您遇到的任何 .NET 对象应该是透明的,所以我不确定为什么这个对象会爆炸。例如 $xmlDoc.root.ComponentRef.SetAttribute("Id", $newId) 工作正常。很奇怪……
-
一定是这样的。调用 Length 会触发它肯定很奇怪。让我觉得这是一个 PowerShell 错误。也许这就是答案,我们拭目以待;)我不确定 PowerShell 团队是否接受公众的错误报告。
-
JohnB 他们确实接受了错误报告 - 使用实时 ID 登录到 connect.microsoft.com/powershell 并使用 repro 记录错误。
标签: powershell