How to select the following specific XML nodes using XPath?
Question: I have an XML doc like the following:

    
    
    <Objects>
      <object distName="a/b">  </object>
      <object distName="a/b/c1">  </object>
      <object distName="a/b/c4/d/e">  </object>
      <object distName="a/b/c2">  </object>
      <object distName="a/b/c6/d">  </object>
    </Objects>
    

And I need to select all nodes which has a path that ends with **"c" +
number**. Like: "_a/b/c1_ " and "_a/b/c2_ " but not like "_a/b/c6/d_ ", nor
"_a/b/c4/d/e_ ".

If I try the following:

    
    
          `cNodes = xmlDoc.xpath("//object[contains(@path, `a/b/c`)]")`
    

Then this will include "a/b/c6/d" and "a/b/c4/d/e" which is not what I
require.

So is there a way to do the job **_in one or maybe two lines of code_**. I
mean I can do it with like a loop and stuff like that, which I don't want to.
That's because the real XML doc is thousands of nodes.

PS: Python 2.7, lxml


Answer: I'm afraid this can't be done using pure XPath 1.0 which is XPath version that
`lxml` supports.

As an alternative, you can try to split the attribute by `/`, get the last
split result, and check if it starts with `c`, all in one line using list
comprehension, for example :

    
    
    >>> raw = '''<Objects>
    ...   <object distName="a/b">  </object>
    ...   <object distName="a/b/c1">  </object>
    ...   <object distName="a/b/c4/d/e">  </object>
    ...   <object distName="a/b/c2">  </object>
    ...   <object distName="a/b/c6/d">  </object>
    ... </Objects>'''
    ... 
    >>> from lxml import etree
    >>> xmlDoc = etree.fromstring(raw)
    >>> cNodes = xmlDoc.xpath("//object[contains(@path, 'a/b/c')]")
    >>> result = [etree.tostring(n) for n in cNodes if n.attrib["distName"].split('/')[-1].startswith("c")]
    >>> print result
    ['<object distName="a/b/c1">  </object>\n  ', '<object distName="a/b/c2">  </object>\n  ']
    

