2 new revisions:
Revision: 4b6ddd9a9b5c
Branch: default
Author: Pekka Klärck
Date: Fri Oct 19 06:44:07 2012
Log: XMLlib: Enhanced `Remove Element(s)`....
http://code.google.com/p/robotframework/source/detail?r=4b6ddd9a9b5c
Revision: a8c284c4b0b1
Branch: default
Author: Pekka Klärck
Date: Fri Oct 19 06:56:29 2012
Log: XML lib: Better approach to handle invalid xpath with Remove
Element(s...
http://code.google.com/p/robotframework/source/detail?r=a8c284c4b0b1
==============================================================================
Revision: 4b6ddd9a9b5c
Branch: default
Author: Pekka Klärck
Date: Fri Oct 19 06:44:07 2012
Log: XMLlib: Enhanced `Remove Element(s)`.
Update issue 1234
Remove Element and Remove Elements now keep tail by default but can remove
it if `remove_tail` is set. This is consistent with `Clear Element` and its
`clear_tail` argument.
http://code.google.com/p/robotframework/source/detail?r=4b6ddd9a9b5c
Modified:
/atest/robot/standard_libraries/xml/add_and_remove_elements.txt
/atest/testdata/standard_libraries/xml/add_and_remove_elements.txt
/src/robot/libraries/XML.py
=======================================
--- /atest/robot/standard_libraries/xml/add_and_remove_elements.txt Thu Oct
18 03:16:33 2012
+++ /atest/robot/standard_libraries/xml/add_and_remove_elements.txt Fri Oct
19 06:44:07 2012
@@ -25,6 +25,15 @@
Remove Non-Direct Child Element
Check Test Case ${TESTNAME}
+
+Remove Element Keeps Tail By Default
+ Check Test Case ${TESTNAME}
+
+Remove Element Can Be Configured To Remove Tail
+ Check Test Case ${TESTNAME}
+
+Remove Element Keeps Tail When Parent or Sibling Contains No Text
+ Check Test Case ${TESTNAME}
Remove Element Fails If No Element Match
Check Test Case ${TESTNAME}
@@ -49,6 +58,12 @@
Remove Elements Does Not Fail If No Element Match
Check Test Case ${TESTNAME}
+
+Remove Elements Keeps Tail By Default
+ Check Test Case ${TESTNAME}
+
+Remove Elements Can Be Configured To Remove Tail
+ Check Test Case ${TESTNAME}
Remove Elements Requires Xpath
Check Test Case ${TESTNAME}
=======================================
--- /atest/testdata/standard_libraries/xml/add_and_remove_elements.txt Thu
Oct 18 03:16:33 2012
+++ /atest/testdata/standard_libraries/xml/add_and_remove_elements.txt Fri
Oct 19 06:44:07 2012
@@ -1,9 +1,11 @@
*** Settings ***
-Resource resource.txt
-Test Setup Parse XML To Test Variable ${SIMPLE} \${XML}
+Resource resource.txt
+Test Setup Parse XML To Test Variable ${SIMPLE} \${XML}
*** Variables ***
-${NEW} <new attr="value"/>
+${NEW} <new attr="value"/>
+${WITH TAIL} <p>text with <b>bold</b>&<i>italics</i>...</p>
+${WITH TAIL 2} <p><b>bold</b><i>italics</i>...</p>
*** Test Cases ***
@@ -43,6 +45,24 @@
Remove Element ${XML} c2/gc
Element Should Not Exist ${XML} c2/gc
+Remove Element Keeps Tail By Default
+ ${p} = Remove Element ${WITH TAIL} i
+ Elements Should Be Equal ${p} <p>text with
<b>bold</b>&...</p>
+ Remove Element ${p} b
+ Elements Should Be Equal ${p} <p>text with &...</p>
+
+Remove Element Keeps Tail When Parent or Sibling Contains No Text
+ ${p} = Remove Element ${WITH TAIL2} i
+ Elements Should Be Equal ${p} <p><b>bold</b>...</p>
+ Remove Element ${p} b
+ Elements Should Be Equal ${p} <p>...</p>
+
+Remove Element Can Be Configured To Remove Tail
+ ${p} = Remove Element ${WITH TAIL} i remove_tail=True
+ Elements Should Be Equal ${p} <p>text with <b>bold</b>&</p>
+ Remove Element ${p} b remove_tail=YeS
+ Elements Should Be Equal ${p} <p>text with </p>
+
Remove Element Fails If No Element Match
[Documentation] FAIL No element matching 'nonex' found.
Remove Element ${XML} nonex
@@ -75,6 +95,16 @@
Remove Elements Does Not Fail If No Element Match
Remove Elements ${XML} nonex
+Remove Elements Keeps Tail By Default
+ ${p} = Remove Elements ${WITH TAIL} xpath=*
+ Elements Should Be Equal ${p} <p>text with &...</p>
+ ${p} = Remove Elements ${WITH TAIL 2} xpath=*
+ Elements Should Be Equal ${p} <p>...</p>
+
+Remove Elements Can Be Configured To Remove Tail
+ ${p} = Remove Elements ${WITH TAIL} xpath=*
remove_tail=please
+ Elements Should Be Equal ${p} <p>text with </p>
+
Remove Elements Requires Xpath
[Documentation] FAIL No xpath given.
Remove Elements ${XML}
@@ -86,4 +116,3 @@
Remove Elements Returns Root Element
${root} = Remove Elements ${SIMPLE} xpath=c2
Element Should Not Exist ${root} xpath=c2
-
=======================================
--- /src/robot/libraries/XML.py Fri Oct 19 04:51:03 2012
+++ /src/robot/libraries/XML.py Fri Oct 19 06:44:07 2012
@@ -994,7 +994,7 @@
parent.insert(int(index), element)
return source
- def remove_element(self, source, xpath=''):
+ def remove_element(self, source, xpath='', remove_tail=False):
"""Removes the element matching `xpath` from the `source`
structure.
The element to remove from the `source` is specified with `xpath`
@@ -1002,21 +1002,27 @@
`source` structure is modified and also returned.
The keyword fails if `xpath` does not match exactly one element.
- Use `Remove Elements` to remove all matched elements and `Add
Element`
- to add new ones.
+ Use `Remove Elements` to remove all matched elements.
+
+ Element's tail text is not removed by default, but that can be
changed
+ by giving `remove_tail` a true value (e.g. any non-empty string).
+ See `Element attributes` section for more information about tail in
+ general.
Examples using `${XML}` structure from `Example`:
| Remove Element | ${XML} | xpath=second |
| Element Should Not Exist | ${XML} | xpath=second |
+ | Remove Element | ${XML} | xpath=html/p/b |
remove_tail=yes |
+ | Element Text Should Be | ${XML} | Text with italics. |
xpath=html/p | normalize_whitespace=yes |
New in Robot Framework 2.7.5.
"""
source = self.get_element(source)
self._verify_removing_xpath(xpath)
- self._remove_element(source, self.get_element(source, xpath))
+ self._remove_element(source, self.get_element(source, xpath),
remove_tail)
return source
- def remove_elements(self, source, xpath=''):
+ def remove_elements(self, source, xpath='', remove_tail=False):
"""Removes all elements matching `xpath` from the `source`
structure.
The elements to remove from the `source` are specified with `xpath`
@@ -1026,6 +1032,9 @@
It is not a failure if `xpath` matches no elements. Use `Remove
Element`
to remove exactly one element and `Add Element` to add new ones.
+ Element's tail text is not removed by default, but that can be
changed
+ by using `remove_tail` argument similarly as with `Remove Element`.
+
Examples using `${XML}` structure from `Example`:
| Remove Elements | ${XML} | xpath=*/child |
| Element Should Not Exist | ${XML} | xpath=second/child |
@@ -1036,7 +1045,7 @@
source = self.get_element(source)
self._verify_removing_xpath(xpath)
for element in self.get_elements(source, xpath):
- self._remove_element(source, element)
+ self._remove_element(source, element, remove_tail)
return source
def _verify_removing_xpath(self, xpath):
@@ -1045,8 +1054,10 @@
if xpath == '.':
raise RuntimeError('Cannot remove root element.')
- def _remove_element(self, root, element):
+ def _remove_element(self, root, element, remove_tail=False):
parent = self._find_parent(root, element)
+ if element.tail and not remove_tail:
+ self._preserve_tail(element, parent)
parent.remove(element)
def _find_parent(self, root, element):
@@ -1055,6 +1066,14 @@
if child is element:
return parent
+ def _preserve_tail(self, element, parent):
+ index = list(parent).index(element)
+ if index == 0:
+ parent.text = (parent.text or '') + element.tail
+ else:
+ sibling = parent[index-1]
+ sibling.tail = (sibling.tail or '') + element.tail
+
def clear_element(self, source, xpath='.', clear_tail=False):
"""Clears the contents of the specified element.
==============================================================================
Revision: a8c284c4b0b1
Branch: default
Author: Pekka Klärck
Date: Fri Oct 19 06:56:29 2012
Log: XML lib: Better approach to handle invalid xpath with Remove
Element(s). Earlier handled xpath pointin to root element only if it
was '.'.
http://code.google.com/p/robotframework/source/detail?r=a8c284c4b0b1
Modified:
/src/robot/libraries/XML.py
=======================================
--- /src/robot/libraries/XML.py Fri Oct 19 06:44:07 2012
+++ /src/robot/libraries/XML.py Fri Oct 19 06:56:29 2012
@@ -462,6 +462,8 @@
"""
if isinstance(source, basestring):
source = self.parse_xml(source)
+ if not xpath:
+ raise RuntimeError('No xpath given.')
if xpath == '.': # ET < 1.3 does not support '.' alone.
return [source]
return source.findall(self._get_xpath(xpath))
@@ -1018,7 +1020,6 @@
New in Robot Framework 2.7.5.
"""
source = self.get_element(source)
- self._verify_removing_xpath(xpath)
self._remove_element(source, self.get_element(source, xpath),
remove_tail)
return source
@@ -1043,17 +1044,10 @@
New in Robot Framework 2.7.5.
"""
source = self.get_element(source)
- self._verify_removing_xpath(xpath)
for element in self.get_elements(source, xpath):
self._remove_element(source, element, remove_tail)
return source
- def _verify_removing_xpath(self, xpath):
- if not xpath:
- raise RuntimeError('No xpath given.')
- if xpath == '.':
- raise RuntimeError('Cannot remove root element.')
-
def _remove_element(self, root, element, remove_tail=False):
parent = self._find_parent(root, element)
if element.tail and not remove_tail:
@@ -1065,6 +1059,7 @@
for child in parent:
if child is element:
return parent
+ raise RuntimeError('Cannot remove root element.')
def _preserve_tail(self, element, parent):
index = list(parent).index(element)