XPath选择祖先节点

5
我将尝试找到一种公式,根据元素在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中有一个函数,它可以从顶部递归地向下迭代,并在每个“Content”元素上生成祖先Url值的连接。因此,它应该连续为每个“Content”节点生成以下内容:
http://mysite.abc
http://mysite.abc/sub1
http://mysite.abc/sub1/sub2
http://mysite.abc/sub1/sub2/sub3

我目前使用的起点是: ($Node =“Content”元素)

$Sites = $Node | Select-XML -XPath  "//ancestor::Site"

但是对于每个$Node,它选择所有的“Site”元素。在向下遍历xml结构时,它会期望找到更多的祖先。
如果有人知道如何直接使用XPath连接这些值,那就太好了,但首先,我很想知道我的当前方法出了什么问题。
2个回答

5

//ancestor::Site 将为您提供与树中 任何 节点 (//) 相关的祖先 Site 节点。

使用 ./ancestor::Site 只获取相对于当前节点 (.) 的祖先节点:

$Sites = $Node | Select-XML -XPath  "./ancestor::Site"

谢谢 Mathias!! - oysterhoys

1

为了提供一个Mathias R. Jessen有用的答案的替代方案(该答案很好地解释了您的方法存在的问题并提供了有效的解决方案):

由于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
}

很高兴听到这个消息。我认为它应该是一个勾号。 - mklement0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接