我在Windows 8 PC上使用Powershell 3.0。我有简单的XML文件,其中包含这样的内容(没有foobar部分,稍后会出现):
<MyData>
<Version>1.2a</Version>
<Version foobar="1">3.4b</Version>
<Version>5.6c</Version>
</MyData>
现在,我一直在将所有版本提取到一个数组中:
[xml] $FileData = Get-Content .\thefile.xml
[array]$theVersions = $FileData.MyData.Version | % {$_}
一切正常,直到我将foobar="1"
添加到XML文件中 - 这似乎打破了一切。我挖了一下,尝试了#text和InnerText的事情:
[array]$theVersions = $FileData.MyData.Version | % {$_.'#text'}
但这个仅适用于一件与foobar;另外两个似乎是看不见的。当然,我可以为文件中的所有数据添加一些(任何)属性,但这不是一个可行的解决方案。
我的问题:是否有一致的方式从这些XML节点中读取Value(或#text或InnerText,无论您喜欢调用它) em>是否存在属性?实际上,我的脚本需要考虑是否存在属性。
后续行动:感谢Keith的建议和一些调整,我能够使用Select-XML来克服我的问题。因为我确实需要那个属性(我最初离开了那个细节,因为我觉得它不重要),我最终得到了这样的格式:
[xml] $FileData = Get-Content .\thefile.xml
[array]$theVersions = (Select-Xml $FileData -XPath '//MyData/Version').Node | % {if ($_.foobar -ne $null) { "$($_.'#text') And Foobar $($_.foobar)"} else {$_.'#text'} }
$theVersions
结果输出:
1.2a
3.4b And Foobar 1
5.6c
谢谢大家!希望这个问题和解决方案可以帮助别人!
答案 0 :(得分:2)
如果您想使用Select-Xml
,请按以下步骤操作:
$xml = [xml]@'
<MyData>
<Version>1.2a</Version>
<Version foobar="1">3.4b</Version>
<Version>5.6c</Version>
</MyData>
'@
(Select-Xml $xml -XPath '//Version/text()').Node.Value
如果要将Version
下的元素限制为仅将MyData
下的元素更改为/MyData/Version/text()
,则会找到名为MyData
的任何元素。这假定{{1}}是root / doc元素。
答案 1 :(得分:1)
您可以随时只过滤字符串......
PS C:\Users\TMTech> [xml]$testxml = @"
<MyData>
<Version>1.2a</Version>
<Version foobar="1">3.4b</Version>
<Version>5.6c</Version>
</MyData>
"@
PS C:\Users\TMTech> $Versions = $testxml.MyData.Version | ?{$_.GetType().Name -eq "String"}
PS C:\Users\TMTech> $Versions
1.2a
5.6c