我有以下XML文件:
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema
-design/2011">
<Metadata>
<Identity Language="en-US" Id="sample-extension" Version="0.1.0" Publisher="wouterdekortplayground"/>
<DisplayName>Sample Extension</DisplayName>
<Description xml:space="preserve">This is the extension file from the contributions guide example on GitHub. Feel free to add or remove sections as y
ou see fit.</Description>
<GalleryFlags/>
<Tags>Sample</Tags>
<Properties>
<Property Id="Microsoft.VisualStudio.Services.Links.Home" Value="https://bit.ly"/>
<Property Id="Microsoft.VisualStudio.Services.Links.Getstarted" Value="https://bit.ly"/>
<Property Id="Microsoft.VisualStudio.Services.Links.Learn" Value="https://bit.ly"/>
<Property Id="Microsoft.VisualStudio.Services.Links.Support" Value="https://bit.ly"/>
<Property Id="Microsoft.VisualStudio.Services.Links.Repository" Value="https://bit.ly"/>
<Property Id="Microsoft.VisualStudio.Services.Links.Issues" Value="https://bit.ly"/>
<Property Id="Microsoft.VisualStudio.Services.Branding.Color" Value="#dcebfc"/>
<Property Id="Microsoft.VisualStudio.Services.Branding.Theme" Value="light"/>
</Properties>
<Categories>Integrate</Categories>
<Icon>img/logo.png</Icon>
</Metadata>
<Dependencies/>
<Installation>
<InstallationTarget Id="Microsoft.VisualStudio.Services"/>
</Installation>
<Assets>
<Asset Type="Microsoft.VisualStudio.Services.Icons.Default" d:Source="File" Path="img/logo.png" Addressable="true"/>
<Asset Type="img/logo.png" d:Source="File" Path="img/logo.png" Addressable="true"/>
<Asset Type="css/app.css" d:Source="File" Path="css/app.css" Addressable="true"/>
<Asset Type="css/jasmine.css" d:Source="File" Path="css/jasmine.css" Addressable="true"/>
<Asset Type="scripts/app.d.ts" d:Source="File" Path="scripts/app.d.ts" Addressable="true"/>
<Asset Type="scripts/app.js" d:Source="File" Path="scripts/app.js" Addressable="true"/>
<Asset Type="scripts/app.js.map" d:Source="File" Path="scripts/app.js.map" Addressable="true"/>
<Asset Type="scripts/app.ts" d:Source="File" Path="scripts/app.ts" Addressable="true"/>
<Asset Type="scripts/Deploy.ps1" d:Source="File" Path="scripts/Deploy.ps1" Addressable="true"/>
<Asset Type="scripts/jasmine-html.js" d:Source="File" Path="scripts/jasmine-html.js" Addressable="true"/>
<Asset Type="scripts/jasmine.js" d:Source="File" Path="scripts/jasmine.js" Addressable="true"/>
<Asset Type="scripts/VSS.SDK.js" d:Source="File" Path="scripts/VSS.SDK.js" Addressable="true"/>
<Asset Type="index.html" d:Source="File" Path="index.html" Addressable="true"/>
<Asset Type="Microsoft.VisualStudio.Services.Manifest" d:Source="File" Path="extension.vsomanifest" Addressable="true"/>
</Assets>
</PackageManifest>
我尝试使用PowerShell修改此XML。我已经从ZIP存档中的文件中读取了文本。然后我将其转换为XML:
[CmdletBinding()]
param(
[string] [Parameter(Mandatory=$true)] $PathToVSIX,
[string] [Parameter(Mandatory=$true)] $Token,
[string] $BaseUrl
)
Set-StrictMode -Version 3
$VerbosePreference = "continue"
$file = Get-ChildItem $PathToVSIX -Filter *.vsix -Recurse |
% { $_.FullName } | Select -First 1
Write-Verbose "Found VSIX Package $file"
# Load ZipFile (Compression.FileSystem) if necessary
try { $null = [IO.Compression.ZipFile] }
catch { [System.Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') }
# Open zip file with update mode (Update, Read, Create -- are the options)
try { $fileZip = [System.IO.Compression.ZipFile]::Open( $file, 'Update' ) }
catch { throw "Another process has locked the '$file' file." }
$desiredFile = [System.IO.StreamReader]($fileZip.Entries | Where-Object { $_.FullName -match 'extension.vsixmanifest' }).Open()
$text = $desiredFile.ReadToEnd()
[xml]$xml = $text | ConvertTo-Xml
$desiredFile.Close()
$desiredFile.Dispose()
一切似乎都没问题,但不知怎的,我无法访问PackageManifest
或其他节点。
当我尝试访问$xml.PackageManifest
时,我收到错误消息
该物业&#39; PackageManifest&#39;在这个对象上找不到。验证该属性是否存在。
我做错了什么?
答案 0 :(得分:1)
您的代码存在(至少)两个问题:
ConvertTo-Xml
并没有像您认为的那样做。它用于将对象转换为XML表示,而不是将XML字符串解析为XML对象,因此结果不是您期望的结果:
PS C:\> [xml]$xml = $text | ConvertTo-Xml
PS C:\> $xml.Save([Console]::Out)
<?xml version="1.0" encoding="ibm850"?>
<Objects>
<Object Type="System.String"><?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schem
as.microsoft.com/developer/vsx-schema
-design/2011">
<Metadata>
<Identity Language="en-US" Id="sample-extension" Version="0.1.0" Publisher="wouterdekortplayground"/>
<DisplayName>Sample Extension</DisplayName>
...
从文档(强调我的):
详细说明
ConvertTo-Xml cmdlet 创建一个或多个Microsoft .NET Framework对象的基于XML的表示。 要使用此cmdlet,请将一个或多个对象传递给cmdlet,或使用InputObject参数指定对象。
你首先不需要它。简单地将XML字符串转换为XML对象就足够了:
[xml]$xml = $text
PS C:\> [xml]$xml = $text
PS C:\> $xml.Save([Console]::Out)
<?xml version="1.0" encoding="ibm850"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.
microsoft.com/developer/vsx-schema -design/2011">
<Metadata>
<Identity Language="en-US" Id="sample-extension" Version="0.1.0" Publisher="wouterdekortplayground" />
<DisplayName>Sample Extension</DisplayName>
...
您的XML数据使用名称空间:
<PackageManifest Version="2.0.0"
xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011"
xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
因此您需要namespace manager来选择节点:
$nsm = New-Object Xml.XmlNamespaceManager($xml.NameTable)
$nsm.AddNamespace('ns', $xml.DocumentElement.xmlns)
$xml.SelectNodes('//ns:PackageManifest', $nsm)