我正在使用PowerShell v3和Windows PowerShell ISE。我有以下这个函数,它很好用:
function Get-XmlNode([xml]$XmlDocument, [string]$NodePath, [string]$NamespaceURI = "", [string]$NodeSeparatorCharacter = '.')
{
# If a Namespace URI was not given, use the Xml document's default namespace.
if ([string]::IsNullOrEmpty($NamespaceURI)) { $NamespaceURI = $XmlDocument.DocumentElement.NamespaceURI }
# In order for SelectSingleNode() to actually work, we need to use the fully qualified node path along with an Xml Namespace Manager, so set them up.
[System.Xml.XmlNamespaceManager]$xmlNsManager = New-Object System.Xml.XmlNamespaceManager($XmlDocument.NameTable)
$xmlNsManager.AddNamespace("ns", $NamespaceURI)
[string]$fullyQualifiedNodePath = Get-FullyQualifiedXmlNodePath -NodePath $NodePath -NodeSeparatorCharacter $NodeSeparatorCharacter
# Try and get the node, then return it. Returns $null if the node was not found.
$node = $XmlDocument.SelectSingleNode($fullyQualifiedNodePath, $xmlNsManager)
return $node
}
现在,我将创建一些类似的函数,因此我想将前三行代码拆分成一个新的函数,这样我就不必在每个地方都复制粘贴它们了,所以我已经这样做了:
function Get-XmlNamespaceManager([xml]$XmlDocument, [string]$NamespaceURI = "")
{
# If a Namespace URI was not given, use the Xml document's default namespace.
if ([string]::IsNullOrEmpty($NamespaceURI)) { $NamespaceURI = $XmlDocument.DocumentElement.NamespaceURI }
# In order for SelectSingleNode() to actually work, we need to use the fully qualified node path along with an Xml Namespace Manager, so set them up.
[System.Xml.XmlNamespaceManager]$xmlNsManager = New-Object System.Xml.XmlNamespaceManager($XmlDocument.NameTable)
$xmlNsManager.AddNamespace("ns", $NamespaceURI)
return $xmlNsManager
}
function Get-XmlNode([xml]$XmlDocument, [string]$NodePath, [string]$NamespaceURI = "", [string]$NodeSeparatorCharacter = '.')
{
[System.Xml.XmlNamespaceManager]$xmlNsManager = Get-XmlNamespaceManager -XmlDocument $XmlDocument -NamespaceURI $NamespaceURI
[string]$fullyQualifiedNodePath = Get-FullyQualifiedXmlNodePath -NodePath $NodePath -NodeSeparatorCharacter $NodeSeparatorCharacter
# Try and get the node, then return it. Returns $null if the node was not found.
$node = $XmlDocument.SelectSingleNode($fullyQualifiedNodePath, $xmlNsManager)
return $node
}
问题在于执行 "return $xmlNsManager" 时会抛出以下错误:Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Xml.XmlNamespaceManager".
因此,即使我已经明确将 $xmlNsManager 变量转换为 System.Xml.XmlNamespaceManager 类型,但当它从 Get-XmlNamespaceManager 函数返回时,PowerShell 会将其转换为对象数组。如果我不将从 Get-XmlNamespaceManager 函数返回的值显式转换为 System.Xml.XmlNamespaceManager,则由于传递到函数的第二个参数的数据类型错误,.SelectSingleNode() 函数将引发以下错误。
Cannot find an overload for "SelectSingleNode" and the argument count: "2".
由于某些原因,PowerShell没有保持返回变量的数据类型。我真的很想从一个函数中让它工作,这样我就不必在各个地方复制粘贴那3行代码了。欢迎提出任何建议,谢谢。
Select-Xml
命令有什么意见呢?使用它的命名空间就像传递一个前缀到命名空间映射的哈希表一样简单,例如$xml | Select-Xml -XPath '//dns:foo' -namespace @{dns='http://schema.foo.org'}
。 - Keith HillSelect-Xml
只是在底层调用XmlDocument
的SelectSingleNode
或SelectNodes
方法,因此仍然容易受到 XML 命名空间的影响,这就是为什么 @Keith 使用了-namespace
参数的原因。 - Andy Arismendi