2012-12-05 45 views
7

我有以下几点:遍历XML元素

$aMyArray = $null 


[xml]$userfile = Get-Content C:\AppSense\Scripts\AmPolicyConversion\AM_dev.xml 

$i = 0 
FOREACH ($j in $userfile.ChildNodes){ 

    FOREACH($k in $j.DocumentElement) { 

    } 

    $i = $i + 1 
} 

我试图通过PowerShell中的每个元素弄清楚如何循环。

然后检查元素上SID的属性。

如果exists存在,则获取属性值并将该值放入一个对象中,并为同一元素获取第二个属性DISPLAYNAME并放入同一个对象中。我们将创建一个对象数组。

我知道我走了,但希望你能帮上忙。

+0

您可以添加更多的细节?比如,你知道xml的样子吗? Powershell允许你在这种情况下通过名称访问,我发现它让代码更容易阅读 – carlpett

回答

11

使用XPath,而不是找到一个SID属性的所有节点,如下所示:

$objs = @() 
$nodes = $userfile.SelectNodes("//*[@SID]") 
foreach ($node in $nodes) { 
    $sid = $node.attributes['SID'].value 
    $dispName = $node.attributes['DISPLAYNAME'].value 
    $obj = new-object psobject -prop @{SID=$sid;DISPNAME=$dispName} 
    $objs += $obj 
} 
$objs 

下面是与输出的例子:

$xml = [xml]@" 
<doc> 
    <foo SID='foosid' DISPLAYNAME="foodisp"> 
    <bar SID='barsid' DISPLAYNAME="bardisp"/> 
    <baz> 
     <blech SID='blechsid' DISPLAYNAME="blechdisp"/> 
    </baz> 
    </foo> 
</doc> 
"@ 

$objs = @() 
$nodes = $xml.SelectNodes("//*[@SID]") 
foreach ($node in $nodes) { 
    $sid = $node.attributes['SID'].value 
    $dispName = $node.attributes['DISPLAYNAME'].value 
    $obj = new-object psobject -prop @{SID=$sid;DISPNAME=$dispName} 
    $objs += $obj 
} 
$objs 

输出:

SID      DISPNAME     
---      --------     
foosid     foodisp     
barsid     bardisp     
blechsid     blechdisp    
+0

我假设你想添加一个语句,在创建多个新的obj空对象之前检查sid是否为空,所以你得到一组相关的objs。 – Anicho

+0

由于XPATH指定元素上存在S​​ID属性,因此我不希望SID有空值 - 可能是空字符串。 –

+0

你是对的,我只是说要高效地存储内存中的内容。看起来像他们提取基于广告的用户的数据可能有1000个,所以每个对象将占用x的内存量,即使它们存储0个属性它只是为以后节省一点空间? – Anicho

2

你也可以在遍历childNodes时引用子节点:

$j.LocalName (the name of the child element) 
$j.InnerXml (the Xml content of the child node)