我试图找到一个公式,根据它在XML层次结构中的位置为元素创建一个URL。
这是我的样本xml:
<Xml>
<Site Url="http://mysite.abc">
<Content></Content>
<SubSites>
<Site Url="/sub1">
<Content></Content>
<SubSites>
<Site Url="/sub2">
<Content></Content>
<SubSites>
<Site Url="/sub3">
<Content></Content>
</Site>
</SubSites>
</Site>
</SubSites>
</Site>
</SubSites>
</Site>
</Xml>
我在Powershell中有一个函数,它从顶部和每个内容递归地向下迭代。元素我想生成祖先Url值的串联。 所以它应该连续生成每个内容&#39;节点:
http://mysite.abc
http://mysite.abc/sub1
http://mysite.abc/sub1/sub2
http://mysite.abc/sub1/sub2/sub3
我现在用作开头: ($ Node =&#39;内容&#39;元素)
$Sites = $Node | Select-XML -XPath "//ancestor::Site"
但对于每个$ Node,它会选择所有&#39; Site&#39;元素。 它期望它在xml结构中找到更多的祖先。
如果有人知道如何将值直接与Xpath连接起来会特别好,但对于初学者来说,我很乐意知道我当前的方法出了什么问题。
答案 0 :(得分:4)
501
将为您提供相对于树中任何节点( Code Eqpmnt
123 501
234 602
456 503
546 504
789 507
)的祖先//ancestor::Site
节点。
使用Site
仅抓取相对于当前节点(//
)的祖先:
./ancestor::Site
答案 1 :(得分:1)
提供Mathias R. Jessen's helpful answer的替代方案(这可以很好地解释您的方法的问题并提供有效的解决方案):
由于 Site
节点似乎始终是任何给定Content
节点的父节点,因此您只需参考具有Site
路径组件的相应..
节点。
此方法允许您立即处理整个文档 :
Select-Xml -LiteralPath sample.xml -XPath "//Content/.." | ForEach-Object -Begin {
$ancestralUrl = ''
} -Process {
$thisUrl = $_.Node.Url
if ($thisUrl -match '^https?://') {
$ancestralUrl = $thisUrl
} else {
$thisUrl = $ancestralUrl += $thisUrl
}
$thisUrl
}
以上产量:
http://mysite.abc
http://mysite.abc/sub1
http://mysite.abc/sub1/sub2
http://mysite.abc/sub1/sub2/sub3
事实上,你甚至可以将上述方法与ancestor
函数结合起来(虽然这里有点矫枉过正):
Select-Xml -LiteralPath sample.xml '//Content/ancestor::Site' | ForEach-Object -Begin {
$ancestralUrl = ''
} -Process {
$thisUrl = $_.Node.Url
if ($thisUrl -match '^https?://') {
$ancestralUrl = $thisUrl
} else {
$thisUrl = $ancestralUrl += $thisUrl
}
$thisUrl
}