Xpath ancestor selection

I am trying to find a formula that creates a URL for an element based on its position in the XML hierarchy.

This is my xml example:

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

I have a function in Powershell that recursively iterates over the top and for each Content element, I want to generate a concatenation of Url values. Therefore, it must generate sequentially for each "Content" Node:

http://mysite.abc
http://mysite.abc/sub1
http://mysite.abc/sub1/sub2
http://mysite.abc/sub1/sub2/sub3

I am currently using as a start: ($ Node = 'Content' element)

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

But for every $ Node, he selects all the elements of the site. He expected him to find more ancestors by going down in the xml structure.

If someone would know how to concatenate values ​​directly using Xpath, that would be especially cool, but for a start I would be happy to know what is happening with my current approach.

+4
2

//ancestor::Site Site node node (//) .

./ancestor::Site node (.):

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

. ( ):

Site node Content node, Site node ...

:

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
}
+1

Source: https://habr.com/ru/post/1694718/


All Articles