0

I'm new to XPath and trying out a few different things, but there's this one query that really doesn't make sense to me.

I want to select all span nodes that don't contain an svg child node, like this:

enter image description here

To me, adding [not(svg)] should stop the query from selecting the exact element that it is selecting, is this some weird behavior or am I being stupid? The XPath query I'm using is:

//div/a/span[not(svg)]

Thanks!

Edit:

The full XPath to the svg node is:

/html/body/div[1]/div[2]/div/div[1]/div[2]/div[1]/div[1]/a/span[1]/svg

And a snippet of the code:

<!DOCTYPE html>
<!-- saved from url=(0019)https://medium.com/ -->
<html xmlns:cc="http://creativecommons.org/ns#" class="">

<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# medium-com: http://ogp.me/ns/fb/medium-com#"></head>

<body itemscope="" class="browser-chrome os-windows is-withMagicUnderlines v-glyph v-glyph--m2 is-js is-resizing" data-action-scope="_actionscope_0" data-gr-c-s-loaded="true">
  <div class="site-main surface-container" id="container">
    <div class="butterBar butterBar--error" data-action-scope="_actionscope_1"></div>
    <div class="surface" id="_obv.shell._surface_1600536527994" style="display: block; visibility: visible;">
      <div class="screenContent surface-content" data-used="true" data-action-scope="_actionscope_2">
        <div class="metabar u-clearfix js-metabar is-withBottomSection metabar--affixed is-transitioning is-maximized">
          <div class="branch-journeys-top"></div>
          <div class="js-metabarMiddle metabar-inner u-marginAuto u-maxWidth1032 u-flexCenter u-justifyContentSpaceBetween u-height65 u-xs-height56 u-paddingHorizontal20">
            <div class="metabar-block u-flex1 u-flexCenter">
              <div class="u-xs-show js-metabarLogoLeft"><a href="https://medium.com/" data-log-event="home" class="siteNav-logo u-fillTransparentBlackDarker u-flex0 u-flexCenter u-paddingTop0"><span class="svgIcon svgIcon--logoMonogram svgIcon--45px"><svg class="svgIcon-use" width="45" height="45"><path d="M5 40V5h35v35H5zm8.56-12.627c0 .555-.027.687-.318 1.03l-2.457 2.985v.396h6.974v-.396l-2.456-2.985c-.291-.343-.344-.502-.344-1.03V18.42l6.127 13.364h.714l5.256-13.364v10.644c0 .29 0 .342-.185.528l-1.848 1.796v.396h9.19v-.396l-1.822-1.796c-.184-.186-.21-.238-.21-.528V15.937c0-.291.026-.344.21-.528l1.823-1.797v-.396h-6.471l-4.622 11.542-5.203-11.542h-6.79v.396l2.14 2.64c.239.292.291.37.291.768v10.353z"></path></svg></span><span class="u-textScreenReader">Homepage</span></a></div>
              <div class="u-xs-hide js-metabarLogoLeft"><a href="https://medium.com/" data-log-event="home" class="siteNav-logo u-fillTransparentBlackDarker u-flex0"><span class="svgIcon svgIcon--logoWordmark svgIcon--112x22px u-xs-hide u-flex"><svg class="svgIcon-use" height="22" width="112" viewBox="0 0 111.5 22"><path d="3-.7V7.3c0-.5 0-1.2.1-1.8L11.4 22h-.1L4.5 6.8c-.1-.4-.2-.4-.3-.6v10c-.1.7 0 1.3.3 1.9l2.7 3.6v.1H0v-.1L2.7 18c.3-.6.4-1.3.3-1.9v-11c0-.5-.1-1.1-.5-1.5L.7 1.1V1h7l5.8 12.9L18.6 1h6.8v.1l-1.9 2.2c-.2.2-.3.5-.3.7v15.2c0 .2.1.5.3.6zm7.6-5.9c0 3.8 1.9 5.3 4.2 5.3 1.9.1 3.6-1 4.4-2.7h.1c-.8 3.7-3.1 5.5-6.5 5.5-3.7 0-7.2-2.2-7.2-7.4 0-5.5 3.5-7.6 7.3-7.6 3.1 0 6.4 1.5 6.4 6.2v.8h-8.7zm0-.8h4.3v-.8c0-3.9-.8-4.9-2-4.9-1.4.1-2.3 1.6-2.3 5.7z"></path></svg></span><span class="svgIcon svgIcon--logoWordmark svgIcon--122x45px u-xs-show u-flex"><svg class="svgIcon-use" width="122" height="45"><path d="0 00-.487-1.602l-2.089-2.708v-.065h7.494l6.277 13.686 5.527-13.686h7.335v.065l-2.061 2.296a.806.806 0 00-.319.786v16.15a.75.75 0 00.319.759zm8.215-6.332v.065c0 4.01 2.07 5.62 4.497 5.62a5.105 5.105 0 004.777-2.894h.066c-.844 3.963-3.298 5.836-6.97 5.836-3.962 0-7.7-2.389-7.7-7.925 0-5.817 3.747-8.14 7.887-8.14 3.335 0 6.886 1.573 6.886 6.632v.806h-9.443zm0-.806h4.618v-.815c0-4.122-.852-5.218-2.136-5.218-1.555 0-2.5 1.64-2.5 6.033h.018z"></path></svg></span><span class="u-textScreenReader">Homepage</span></a></div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>

</html>

Additionally, the XPath to the top div element of the code snippet above is:

/html/body/div[1]/div[2]/div/div[1]/div[2]/div[1]/div[1]
James Briggs
  • 854
  • 6
  • 13
  • 2
    Yes, I think your expectations are right. Please supply your code in a form where others can run in (ie. a complete example, not fragments, and not images) so people can try to reproduce it. – Michael Kay Sep 19 '20 at 21:37
  • @MichaelKay I've added more code to the post, I hope this is better, thanks. – James Briggs Sep 19 '20 at 22:20
  • 1
    You've still not created a [mcve] illustrating the problem. SVG elements are typically in a different namespace. You've not shown where you've added `[not(svg)]`. Etc. Read that link and provide a complete, minimum, ***reproducible*** example that can be reproduced without us having guess what you did. Thanks. – kjhughes Sep 20 '20 at 04:15
  • 1
    If you're running in the browser and this is an HTML DOM, then it could be a namespace issue. See https://stackoverflow.com/questions/23319537/html-5-inline-svg-and-namespace-awareness-for-svg-dom – Michael Kay Sep 20 '20 at 07:43
  • @kjhughes The full HTML doc is ~25K lines, I've tried to just cut out a part of that which covers the small part of the scope which I was finding this issue with, is it better? Although I think you and Michael are correct with it being due to being in a different namespace. – James Briggs Sep 20 '20 at 12:56
  • Between the [link](https://stackoverflow.com/q/23319537/290085) @MichaelKay provided that teaches that `svg` is loaded into the DOM in the SVG namespace, even if it's not explicitly defined in the HTML, and [How does XPath deal with XML namespaces?](https://stackoverflow.com/q/40796231/290085), which teaches how to reference namespace nodes for many different XPath hosting languages, I believe you should be good to go. – kjhughes Sep 20 '20 at 13:47

1 Answers1

0

For anyone who stumbles across this, the issue was due to SVG and HTML namespace differences, which are covered in the answers included in MichealKay's comments.

To select the SVG element, I had to write:

//span/*[name()="svg"]
James Briggs
  • 854
  • 6
  • 13