Импорт-Clixml PowerShell из строки - PullRequest
5 голосов
/ 03 марта 2010

Есть ли способ выполнить командлет Import-Clixml для строки или объекта XML?

Требуется путь файла в качестве входных данных для создания объектов PowerShell, и он не может получить входные данные от объекта XML. Поскольку существует командлет ConvertTo-Xml , который сериализует объект PowerShell в объект XML, почему нет преобразования из XML, что могло бы сделать обратное?

Я знаю о классе System.Xml.Serialization.XmlSerializer, который сделал бы именно это. Однако для этого я бы хотел использовать командлеты.

Есть ли способ сделать это с помощью командлетов (возможно, только с Import-Clixml), не создавая временные файлы?

Ответы [ 3 ]

1 голос
/ 07 марта 2010

Кто-то написал функцию ConvertTo-CliXml .

Так что должна быть возможность написать функцию ConvertFrom-CliXml аналогичным образом. Вы должны проверить командлет Export-CliXml в .NET Reflector , чтобы убедиться, что больше ничего не нужно делать.

Существует также сообщение об ошибке в Connect об этом:

Я знаю, что это не решит вашу проблему немедленно, но единственный другой способ - использовать временные файлы для ввода и вывода командлетов * -CliXml.

1 голос
/ 11 октября 2010

Я написал это на основе 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: $_"
            }
        }
    }
}
1 голос
/ 03 марта 2010

Очевидной попыткой было бы просто указать путь к переменной:

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 и преобразовывать его обратно?

В противном случае вы все еще можете заключить временные файлы в функцию.

...