Skip to content

Commit f31ffb0

Browse files
committed
Fix XML library with bytes inputs
This was mostly fixed by issue robotframework#3194. This commit adds tests and fixes directly getting information from XML specified as bytes. Fixes robotframework#3226.
1 parent 8b25610 commit f31ffb0

10 files changed

Lines changed: 134 additions & 8 deletions

File tree

atest/robot/standard_libraries/xml/get_elements.robot

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ Get element from xml file
1313
Get element from xml string
1414
Check Test Case ${TESTNAME}
1515

16+
Get element from xml bytes
17+
Check Test Case ${TESTNAME}
18+
1619
Get element with named xpath
1720
Check Test Case ${TESTNAME}
1821

@@ -28,6 +31,12 @@ Get element fails when no elements match
2831
Get elements
2932
Check Test Case ${TESTNAME}
3033

34+
Get elements from xml string
35+
Check Test Case ${TESTNAME}
36+
37+
Get elements from xml bytes
38+
Check Test Case ${TESTNAME}
39+
3140
Get elements returns empty list when no elements match
3241
Check Test Case ${TESTNAME}
3342

atest/robot/standard_libraries/xml/get_elements_with_lxml.robot

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ Get element from xml file
1313
Get element from xml string
1414
Check Test Case ${TESTNAME}
1515

16+
Get element from xml bytes
17+
Check Test Case ${TESTNAME}
18+
1619
Get element with named xpath
1720
Check Test Case ${TESTNAME}
1821

@@ -28,6 +31,12 @@ Get element fails when no elements match
2831
Get elements
2932
Check Test Case ${TESTNAME}
3033

34+
Get elements from xml string
35+
Check Test Case ${TESTNAME}
36+
37+
Get elements from xml bytes
38+
Check Test Case ${TESTNAME}
39+
3140
Get elements returns empty list when no elements match
3241
Check Test Case ${TESTNAME}
3342

atest/robot/standard_libraries/xml/parsing.robot

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ Parse file using system path separator
1212
Parse string
1313
Check Test Case ${TESTNAME}
1414

15+
Parse string with encoding
16+
Check Test Case ${TESTNAME}
17+
18+
Parse bytes
19+
Check Test Case ${TESTNAME}
20+
21+
Parse bytes with encoding
22+
Check Test Case ${TESTNAME}
23+
1524
Comments and processing instructions are removed
1625
Check Test Case ${TESTNAME}
1726

atest/robot/standard_libraries/xml/parsing_with_lxml.robot

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ Parse file using system path separator
1313
Parse string
1414
Check Test Case ${TESTNAME}
1515

16+
Parse string with encoding
17+
Check Test Case ${TESTNAME}
18+
19+
Parse bytes
20+
Check Test Case ${TESTNAME}
21+
22+
Parse bytes with encoding
23+
Check Test Case ${TESTNAME}
24+
1625
Comments and processing instructions are removed
1726
Check Test Case ${TESTNAME}
1827

atest/testdata/standard_libraries/xml/get_elements.robot

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ Get element from xml string
2020
${child}= Get Element <root><tag>text</tag></root> tag
2121
Should Be Equal ${child.text} text
2222

23+
Get element from xml bytes
24+
${child}= Run With Bytes
25+
... Get Element <root><tag>text</tag></root> tag
26+
Should Be Equal ${child.text} text
27+
2328
Get element with named xpath
2429
${child}= Get Element <root><tag>text</tag></root> xpath=tag
2530
Should Be Equal ${child.text} text
@@ -41,6 +46,17 @@ Get elements
4146
Length Should Be ${elements} 3
4247
Should Be Equal ${elements[0].text} child 1 text
4348

49+
Get elements from xml string
50+
${elements}= Get Elements <root><c/><c>xxx</c></root> c
51+
Length Should Be ${elements} 2
52+
Should Be Equal ${elements[1].text} xxx
53+
54+
Get elements from xml bytes
55+
${elements}= Run With Bytes
56+
... Get Elements <root><c/><c>xxx</c></root> c
57+
Length Should Be ${elements} 2
58+
Should Be Equal ${elements[1].text} xxx
59+
4460
Get elements returns empty list when no elements match
4561
${elements}= Get Elements ${TEST} non-existing
4662
Should Be Empty ${elements}

atest/testdata/standard_libraries/xml/get_elements_with_lxml.robot

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ Get element from xml string
2121
${child}= Get Element <root><tag>text</tag></root> tag
2222
Should Be Equal ${child.text} text
2323

24+
Get element from xml bytes
25+
${child}= Run With Bytes
26+
... Get Element <root><tag>text</tag></root> tag
27+
Should Be Equal ${child.text} text
28+
2429
Get element with named xpath
2530
${child}= Get Element <root><tag>text</tag></root> xpath=tag
2631
Should Be Equal ${child.text} text
@@ -42,6 +47,17 @@ Get elements
4247
Length Should Be ${elements} 3
4348
Should Be Equal ${elements[0].text} child 1 text
4449

50+
Get elements from xml string
51+
${elements}= Get Elements <root><c/><c>xxx</c></root> c
52+
Length Should Be ${elements} 2
53+
Should Be Equal ${elements[1].text} xxx
54+
55+
Get elements from xml bytes
56+
${elements}= Run With Bytes
57+
... Get Elements <root><c/><c>xxx</c></root> c
58+
Length Should Be ${elements} 2
59+
Should Be Equal ${elements[1].text} xxx
60+
4561
Get elements returns empty list when no elements match
4662
${elements}= Get Elements ${TEST} non-existing
4763
Should Be Empty ${elements}

atest/testdata/standard_libraries/xml/parsing.robot

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,31 @@ Parse string
1616
Should be equal ${root.tag} simple
1717
Should be equal ${root.text} päivää
1818

19+
Parse string with encoding
20+
${root} = Parse XML <?xml version="1.0" encoding="UTF-8"?><simple>päivää</simple>
21+
Should be equal ${root.tag} simple
22+
Should be equal ${root.text} päivää
23+
${root} = Parse XML <?xml version='1.0' encoding='latin1' standalone='yes'?>\n<simple>päivää</simple>\n
24+
Should be equal ${root.tag} simple
25+
Should be equal ${root.text} päivää
26+
27+
Parse bytes
28+
${root} = Run With Bytes
29+
... Parse XML <simple>päivää</simple>
30+
Should be equal ${root.tag} simple
31+
Should be equal ${root.text} päivää
32+
33+
Parse bytes with encoding
34+
${root} = Run With Bytes
35+
... Parse XML <?xml version\="1.0" encoding\="UTF-8"?><simple>päivää</simple>
36+
Should be equal ${root.tag} simple
37+
Should be equal ${root.text} päivää
38+
${root} = Run With Bytes
39+
... Parse XML <?xml version\='1.0' encoding\='latin1' standalone\='yes'?>\n<simple>päivää</simple>\n
40+
... encoding=latin1
41+
Should be equal ${root.tag} simple
42+
Should be equal ${root.text} päivää
43+
1944
Comments and processing instructions are removed
2045
${xml} = Catenate SEPARATOR=\n
2146
... <!-- comment node -->

atest/testdata/standard_libraries/xml/parsing_with_lxml.robot

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,31 @@ Parse string
1717
Should be equal ${root.tag} simple
1818
Should be equal ${root.text} päivää
1919

20+
Parse string with encoding
21+
${root} = Parse XML <?xml version="1.0" encoding="UTF-8"?><simple>päivää</simple>
22+
Should be equal ${root.tag} simple
23+
Should be equal ${root.text} päivää
24+
${root} = Parse XML <?xml version='1.0' encoding='latin1' standalone='yes'?>\n<simple>päivää</simple>\n
25+
Should be equal ${root.tag} simple
26+
Should be equal ${root.text} päivää
27+
28+
Parse bytes
29+
${root} = Run With Bytes
30+
... Parse XML <simple>päivää</simple>
31+
Should be equal ${root.tag} simple
32+
Should be equal ${root.text} päivää
33+
34+
Parse bytes with encoding
35+
${root} = Run With Bytes
36+
... Parse XML <?xml version\="1.0" encoding\="UTF-8"?><simple>päivää</simple>
37+
Should be equal ${root.tag} simple
38+
Should be equal ${root.text} päivää
39+
${root} = Run With Bytes
40+
... Parse XML <?xml version\='1.0' encoding\='latin1' standalone\='yes'?>\n<simple>päivää</simple>\n
41+
... encoding=latin1
42+
Should be equal ${root.tag} simple
43+
Should be equal ${root.text} päivää
44+
2045
Comments and processing instructions are removed
2146
${xml} = Catenate SEPARATOR=\n
2247
... <!-- comment node -->

atest/testdata/standard_libraries/xml/xml_resource.robot

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ Get Etree Version
1717
${et} = Evaluate robot.utils.ET modules=robot
1818
[Return] ${et.VERSION}
1919

20+
Run With Bytes
21+
[Arguments] ${kw} ${string} @{args} ${encoding}=UTF-8 &{kws}
22+
${bytes} = Encode string to bytes ${string} ${encoding}
23+
${result} = Run Keyword ${kw} ${bytes} @{args} &{kws}
24+
[Return] ${result}
25+
2026
Parse XML To Test Variable
2127
[Arguments] ${input} ${var} &{config}
2228
${result} = Parse XML ${input} &{config}
@@ -34,7 +40,6 @@ Saved XML Should Equal
3440
${expected} = Catenate SEPARATOR=\n @{expected}
3541
XML Content Should Be ${expected}
3642

37-
3843
Saved XML Should Equal File
3944
[Arguments] ${tree} ${expected}
4045
Remove File ${OUTPUT}

src/robot/libraries/XML.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424

2525
from robot.api import logger
2626
from robot.libraries.BuiltIn import BuiltIn
27-
from robot.utils import (asserts, ET, ETSource, is_falsy, is_string, is_truthy,
28-
plural_or_not as s)
27+
from robot.utils import (asserts, ET, ETSource, is_bytes, is_falsy, is_string,
28+
is_truthy, plural_or_not as s)
2929
from robot.version import get_version
3030

3131

@@ -68,10 +68,11 @@ class XML(object):
6868
= Parsing XML =
6969
7070
XML can be parsed into an element structure using `Parse XML` keyword.
71-
It accepts both paths to XML files and strings that contain XML. The
72-
keyword returns the root element of the structure, which then contains
73-
other elements as its children and their children. Possible comments and
74-
processing instructions in the source XML are removed.
71+
The XML to be parsed can be specified using a path to an XML file or as
72+
a string or bytes that contain XML directly. The keyword returns the root
73+
element of the structure, which then contains other elements as its
74+
children and their children. Possible comments and processing instructions
75+
in the source XML are removed.
7576
7677
XML is not validated during parsing even if has a schema defined. How
7778
possible doctype elements are handled otherwise depends on the used XML
@@ -93,6 +94,8 @@ class XML(object):
9394
escaped by doubling it (``\\\\``). Using the built-in variable ``${/}``
9495
naturally works too.
9596
97+
Note: Support for XML as bytes is new in Robot Framework 3.2.
98+
9699
= Using lxml =
97100
98101
By default this library uses Python's standard
@@ -584,7 +587,7 @@ def get_elements(self, source, xpath):
584587
| ${children} = | Get Elements | ${XML} | first/child |
585588
| Should Be Empty | ${children} | | |
586589
"""
587-
if is_string(source):
590+
if is_string(source) or is_bytes(source):
588591
source = self.parse_xml(source)
589592
finder = ElementFinder(self.etree, self.modern_etree, self.lxml_etree)
590593
return finder.find_all(source, xpath)

0 commit comments

Comments
 (0)