PowerShell更改返回对象的类型 [英] PowerShell changes return object's type

查看:126
本文介绍了PowerShell更改返回对象的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用PowerShell v3和Windows PowerShell ISE。我有以下函数可以正常工作:

pre $函数Get-XmlNode([xml] $ XmlDocument,[string] $ NodePath, [String] $ NamespaceURI =,[string] $ NodeSeparatorCharacter ='。')
{
#如果没有给出名称空间URI,请使用Xml文档的默认名称空间。
if([string] :: IsNullOrEmpty($ NamespaceURI)){$ NamespaceURI = $ XmlDocument.DocumentElement.NamespaceURI}

#为了使SelectSingleNode()实际工作,我们需要使用完全合格的节点路径和一个Xml命名空间管理器,因此设置它们。
[System.Xml.XmlNamespaceManager] $ xmlNsManager = New-Object System.Xml.XmlNamespaceManager($ XmlDocument.NameTable)
$ xmlNsManager.AddNamespace(ns,$ NamespaceURI)

[string] $ fullyQualifiedNodePath = Get-FullyQualifiedXmlNodePath -NodePath $ NodePath -NodeSeparatorCharacter $ NodeSeparatorCharacter

#尝试并获取节点,然后返回它。如果未找到该节点,则返回$ null。
$ node = $ XmlDocument.SelectSingleNode($ fullyQualifiedNodePath,$ xmlNsManager)
return $ node
}

现在,我将创建一些类似的函数,因此我想将前三行分解为一个新函数,这样我就不必将它们复制粘贴到任何地方,所以我已完成此操作:

pre $ 函数Get-XmlNamespaceManager([xml] $ XmlDocument,[string] $ NamespaceURI =)
{
#如果未给出名称空间URI,请使用Xml文档的默认名称空间。
if([string] :: IsNullOrEmpty($ NamespaceURI)){$ NamespaceURI = $ XmlDocument.DocumentElement.NamespaceURI}

#为了使SelectSingleNode()实际工作,我们需要使用完全合格的节点路径和一个Xml命名空间管理器,因此设置它们。
[System.Xml.XmlNamespaceManager] $ xmlNsManager = New-Object System.Xml.XmlNamespaceManager($ XmlDocument.NameTable)
$ xmlNsManager.AddNamespace(ns,$ NamespaceURI)
return $ xmlNsManager


函数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

#尝试并获取节点,然后返回它。如果未找到该节点,则返回$ null。
$ node = $ XmlDocument.SelectSingleNode($ fullyQualifiedNodePath,$ xmlNsManager)
return $ node
}

问题是,当return $ xmlNsManager执行时会抛出以下错误:

 无法将类型为System.Object []的System.Object []值转换为键入System.Xml.XmlNamespaceManager。 

因此,即使我明确地将我的$ xmlNsManager变量转换为System.Xml.XmlNamespaceManager类型,当它从Get-XmlNamespaceManager函数返回时,PowerShell将它转换为一个Object数组。



如果我没有明确地转换Get-XmlNamespaceManager函数返回的值到System.Xml.XmlNamespaceManager,然后从.SelectSingleNode()函数抛出以下错误,因为错误的数据类型正在传递到函数的第二个参数。

 无法找到SelectSingleNode的重载和参数计数:2。 

因此PowerShell并不维护返回变量的数据类型。我真的很想从一个函数中获得这个工作,这样我就不必在整个地方复制粘贴这3行代码。任何建议表示赞赏。感谢。

解决方案

PowerShell正在将名称空间管理器对象转换为字符串数组。



我认为这与PowerShell在向管道发送对象时展开集合的本质有关。我认为PowerShell将为任何实现IEnumerable的类型(具有GetEnumerator方法)执行此操作。



作为解决方案,您可以使用逗号技巧来防止此行为并发送对象作为一个整体集合。

 函数Get-XmlNamespaceManager([xml] $ XmlDocument,[string] $ NamespaceURI =) 
{
...
$ xmlNsManager.AddNamespace(ns,$ NamespaceURI)
return,$ xmlNsManager
}


I am using PowerShell v3 and the Windows PowerShell ISE. I have the following function that works fine:

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
}

Now, I will be creating a few similar functions, so I want to break the first 3 lines out into a new function so that I don't have to copy-paste them everywhere, so I have done this:

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
}

The problem is that when "return $xmlNsManager" executes the following error is thrown:

Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Xml.XmlNamespaceManager".

So even though I have explicitly cast my $xmlNsManager variables to be of type System.Xml.XmlNamespaceManager, when it gets returned from the Get-XmlNamespaceManager function PowerShell is converting it to an Object array.

If I don't explicitly cast the value returned from the Get-XmlNamespaceManager function to System.Xml.XmlNamespaceManager, then the following error is thrown from the .SelectSingleNode() function because the wrong data type is being passed into the function's 2nd parameter.

Cannot find an overload for "SelectSingleNode" and the argument count: "2".

So for some reason PowerShell is not maintaining the data type of the return variable. I would really like to get this working from a function so that I don't have to copy-paste those 3 lines all over the place. Any suggestions are appreciated. Thanks.

解决方案

What's happening is PowerShell is converting your namespace manager object to a string array.

I think it has to do with PowerShell's nature of "unrolling" collections when sending objects down the pipeline. I think PowerShell will do this for any type implementing IEnumerable (has a GetEnumerator method).

As a work around you can use the comma trick to prevent this behavior and send the object as a whole collection.

function Get-XmlNamespaceManager([xml]$XmlDocument, [string]$NamespaceURI = "")
{
    ...
    $xmlNsManager.AddNamespace("ns", $NamespaceURI)
    return ,$xmlNsManager
}

这篇关于PowerShell更改返回对象的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆