有没有办法在字符串或XML对象上运行Import-Clixml
cmdlet?
它需要一个文件路径作为输入来生成PowerShell对象,并且无法从XML对象获取输入。由于有ConvertTo-Xml cmdlet将PowerShell对象序列化为XML对象,为什么不能从XML转换,这会反过来呢?
我知道System.Xml.Serialization.XmlSerializer
类可以做到这一点。但是,我想坚持使用cmdlet来做到这一点。
有没有办法使用cmdlet(可能只有Import-Clixml
),而不创建临时文件?
答案 0 :(得分:1)
显而易见的尝试是给出变量的路径:
PS Home:\> $xmldata = gci | ConvertTo-Xml
PS Home:\> Import-Clixml Variable:\xmldata
Import-Clixml : Cannot open file because the current provider (Microsoft.PowerShell.Core\Variable) cannot open a file.
At line:1 char:14
+ Import-Clixml <<<< Variable:\xmldata
+ CategoryInfo : InvalidArgument: (:) [Import-Clixml], PSInvalidOperationException
+ FullyQualifiedErrorId : ReadWriteFileNotFileSystemProvider,Microsoft.PowerShell.Commands.ImportClixmlCommand
......遗憾地失败了。所以我假设没有真正的方法可以在没有临时文件的情况下工作。
ConvertTo-XML
的要点是在将对象转换为XML后允许在PowerShell中进一步处理XML。所以问题是为什么你不能直接对对象进行更改而不是操纵XML并将其转换回来?
否则你仍然可以将临时文件包装到函数中。
答案 1 :(得分:1)
有人写了ConvertTo-CliXml function。
因此应该可以以类似的方式编写ConvertFrom-CliXml函数。您应该检查.NET Reflector中的Export-CliXml cmdlet,以确保不需要执行任何其他操作。
关于此问题还有a bug report on Connect:
我知道这并不能立即解决您的问题,但唯一的另一种方法是使用临时文件作为* -CliXml cmdlet的输入和输出。
答案 2 :(得分:1)
我是根据ConvertFrom-CliXml写的。它似乎工作,虽然我没有彻底测试它。
function ConvertFrom-CliXml {
param(
[parameter(position=0, mandatory=$true, valuefrompipeline=$true)]
[validatenotnull()]
[string]$string
)
begin
{
$inputstring = ""
}
process
{
$inputstring += $string
}
end
{
$type = [type]::gettype("System.Management.Automation.Deserializer")
$ctor = $type.getconstructor("instance,nonpublic", $null, @([xml.xmlreader]), $null)
$sr = new-object io.stringreader $inputstring
$xr = new-object xml.xmltextreader $sr
$deserializer = $ctor.invoke($xr)
$method = @($type.getmethods("nonpublic,instance") | where-object {$_.name -like "Deserialize"})[1]
$done = $type.getmethod("Done", [reflection.bindingflags]"nonpublic,instance")
while (!$done.invoke($deserializer, @()))
{
try {
$method.invoke($deserializer, "")
} catch {
write-warning "Could not deserialize object: $_"
}
}
}
}
答案 3 :(得分:0)
[Management.Automation.PSSerializer]::Deserialize($cliXmlString)
@{ a=1; b = 2,3,4; c = 3.14 } | Export-Clixml -Path ~\Test.clixml
$cliXmlString = ( Get-Content -Path ~\Test.clixml ) -join ''
[Management.Automation.PSSerializer]::Deserialize($cliXmlString)
Name Value
---- -----
c 3.14
a 1
b {2, 3, 4}