Powershell XML:属性是否存在,会改变获取Value的方式

时间:2014-07-24 21:17:11

标签: xml powershell

我在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

谢谢大家!希望这个问题和解决方案可以帮助别人!

2 个答案:

答案 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