我正在尝试处理XML文件(下面的剪辑),我从元素节点中提取了属性。我还想提取标题值(如果存在),并返回该标题值的所有类型属性" group",但仅当它存在时。我不知道如何做到这一点 - 我可以检索标题值,但无法解决如何仅与"组"它有一个标题值。我确定群组是错误的术语,它几乎就像我想从父节点获取标题,但它不会存储在父节点中。
我已经包含了示例输出,希望能够展示我尝试解释的内容。
$xml = [xml]@"
<document document="test">
<elements>
<element type="header">Header1</element>
<element type="link" title="Title1" />
<element type="link" title="Title2" />
<element type="link" title="Title3" />
</elements>
<elements>
<element type="link" title="Title200" />
</elements>
<elements>
<element type="header">Header2</element>
<element type="link" title="Title300" />
<element type="link" title="Title301" />
</elements>
</document>
"@
$objs = @()
$nodes = $xml.SelectNodes("//*[@type]")
foreach ($node in $nodes) {
#$node.ParentNode.ToString()
$type = $node.Attributes['type'].value
if ($type -eq "header") {$header = $node.InnerText}
$title = $node.Attributes['title'].value
$obj = New-Object PSObject -Prop @{TYPE=$type;TITLE=$title;HEADER=$header}
$objs += $obj
}
$header = ""
$objs
我目前得到的输出:
TITLE HEADER TYPE ----- ------ ---- Header1 header Title1 Header1 link Title2 Header1 link Title3 Header1 link Title200 Header1 link Header2 header Title300 Header2 link Title301 Header2 link
我希望输出(Title200
没有显示标题):
TITLE HEADER TYPE ----- ------ ---- Header1 header Title1 Header1 link Title2 Header1 link Title3 Header1 link Title200 link Header2 header Title300 Header2 link Title301 Header2 link
答案 0 :(得分:2)
您没有在每个$header
次传递的开始时初始化foreach
变量,这导致前一个值保留在内部。试试这个:
$objs = @()
$nodes = $xml.SelectNodes("//*[@type]")
foreach ($node in $nodes) {
#$node.ParentNode.ToString()
$header = ""
$type = $node.Attributes['type'].value
if ($type -eq "header") {$header = $node.InnerText}
$title = $node.Attributes['title'].value
$obj = New-Object PSObject -Prop @{TYPE=$type;TITLE=$title;HEADER=$header}
$objs += $obj
}
$header = ""
$objs
答案 1 :(得分:0)
我终于解决了这个问题 - 我可以通过引用父节点然后使用SelectSingleNode来检索属性type ='header'的元素来获取“group”的标题。
$xml = [xml]@"
<document document="test">
<elements>
<element type="header">Header1</element>
<element type="link" title="Title1" />
<element type="link" title="Title2" />
<element type="link" title="Title3" />
</elements>
<elements>
<element type="link" title="Title200" />
</elements>
<elements>
<element type="header">Header2</element>
<element type="link" title="Title300" />
<element type="link" title="Title301" />
</elements>
</document>
"@
cls
$objs = @()
$nodes = $xml.SelectNodes("//*[@type]")
foreach ($node in $nodes) {
$header = ""
$type = $node.Attributes['type'].value
#using the ParentNode, retrieve the element where the attribute type='header'
#and then get the InnerText to get the actual value
$header = $node.ParentNode.SelectSingleNode("element[@type='header']").InnerText
$title = $node.Attributes['title'].value
$obj = New-Object PSObject -Prop @{TYPE=$type;TITLE=$title;HEADER=$header}
if ($type -ne "header") {
$objs += $obj
}
}
$header = ""
$objs
这给出了我正在寻找的输出。可能有更有效的方法,但它确实有效,并有望帮助其他人。
TITLE HEADER TYPE
----- ------ ----
Title1 Header1 link
Title2 Header1 link
Title3 Header1 link
Title200 link
Title300 Header2 link
Title301 Header2 link