Unexpected output when using xpath() twice

When I try to use xpath() method twice, I get unexpected outputs.
I expected 'gekko1' string as output in two last commands. Maybe I have not understood the API correctly? What should I do to get the behavior I expect? FYI if I convert xml_system_list[0] to string and convert it back to XML using tostring() and fromstring(), I get the expected output. Regards, Alan Evangelista

On 08/28/2014 06:30 PM, Frederik Elwert wrote:
This is not an lxml issue, but the defined behaviour in XPath: If you want the expression to be evaluated in the context of the selected node, you must use a relative path. In your case, you probably want './@name' (or just: '@name'). Any absolute path (starting with a slash) is evaluated in the context of the whole tree, no matter on which element you call the xpath method. So your expression '/system/@name' looks for a root element called 'system', which does not exist, hence the empty result.
Thanks for the quick and thorough feedback. I'll try your XPath suggestion. I thought that the first XPath expression mentioned in my first email generated a XML tree which root was 'system'. If the root element does not exist, could you pls explain to me why I see
etree.tostring(xml_system_list[0])
'<system name="gekko1"/> I define the root element as the XML node which encloses an entire block of XML, so 'system' looks a root element to me. What is the root element of this XML? Regards, Alan Evangelista

Am 29.08.2014 um 14:47 schrieb Alan Evangelista:
No, `xml_systems.xpath('/systems/system')` returns a list of *Elements* which are still part of the tree with the root element 'systems'. They are not independent trees: In [11]: xml_system_list[0].getroottree().getroot() Out[11]: <Element systems at 0x7ff198049348> You *could* (theoretically) contruct independent trees from the elements: In [5]: system_tree = etree.ElementTree(xml_system_list[0]) In [6]: system_tree.getroot() Out[6]: <Element system at 0x7ff198049588> But I think in most cases you are better off just working with relative XPath expressions on the elements.
This is because you serialize only an element, not the whole tree. If you parse this serialization again, you get a new tree, for which 'system' is indeed the root.
For the element `xml_system_list[0]`, the root is 'systems', because it is the root of the XML tree that this element is part of. For the subtree that you serialize, 'system' is the root, because you loose that contextual information. I hope this makes it clearer. Best, Frederik

On 08/28/2014 06:30 PM, Frederik Elwert wrote:
This is not an lxml issue, but the defined behaviour in XPath: If you want the expression to be evaluated in the context of the selected node, you must use a relative path. In your case, you probably want './@name' (or just: '@name'). Any absolute path (starting with a slash) is evaluated in the context of the whole tree, no matter on which element you call the xpath method. So your expression '/system/@name' looks for a root element called 'system', which does not exist, hence the empty result.
Thanks for the quick and thorough feedback. I'll try your XPath suggestion. I thought that the first XPath expression mentioned in my first email generated a XML tree which root was 'system'. If the root element does not exist, could you pls explain to me why I see
etree.tostring(xml_system_list[0])
'<system name="gekko1"/> I define the root element as the XML node which encloses an entire block of XML, so 'system' looks a root element to me. What is the root element of this XML? Regards, Alan Evangelista

Am 29.08.2014 um 14:47 schrieb Alan Evangelista:
No, `xml_systems.xpath('/systems/system')` returns a list of *Elements* which are still part of the tree with the root element 'systems'. They are not independent trees: In [11]: xml_system_list[0].getroottree().getroot() Out[11]: <Element systems at 0x7ff198049348> You *could* (theoretically) contruct independent trees from the elements: In [5]: system_tree = etree.ElementTree(xml_system_list[0]) In [6]: system_tree.getroot() Out[6]: <Element system at 0x7ff198049588> But I think in most cases you are better off just working with relative XPath expressions on the elements.
This is because you serialize only an element, not the whole tree. If you parse this serialization again, you get a new tree, for which 'system' is indeed the root.
For the element `xml_system_list[0]`, the root is 'systems', because it is the root of the XML tree that this element is part of. For the subtree that you serialize, 'system' is the root, because you loose that contextual information. I hope this makes it clearer. Best, Frederik
participants (2)
-
Alan Evangelista
-
Frederik Elwert