def _plays_to_games(self, data): def after_players_hook(_, status): return status["name"] if "name" in status else "Unknown" plays_processor = xml.dictionary("plays", [ xml.array( xml.dictionary('play', [ xml.integer(".", attribute="id", alias="playid"), xml.dictionary('item', [ xml.string(".", attribute="name", alias="gamename"), xml.integer(".", attribute="objectid", alias="gameid") ], alias='game'), xml.array( xml.dictionary( 'players/player', [ xml.string(".", attribute="name", required=False, default="Unknown") ], required=False, alias='players', hooks=xml.Hooks(after_parse=after_players_hook))) ], required=False, alias="plays")) ]) plays = xml.parse_from_string(plays_processor, data) plays = plays["plays"] return plays
def test_parse_array_of_arrays(): """Parse array of arrays""" xml_string = """ <root-array> <values> <value>1</value> <value>17</value> <value>33</value> </values> <values> <value>99</value> </values> </root-array> """ values_array = xml.array(xml.integer('value'), nested='values') root_processor = xml.array(values_array, nested='root-array') expected = [ [1, 17, 33], [99], ] actual = xml.parse_from_string(root_processor, xml_string) assert expected == actual
def __init__(self): paraphrase_processor = xml.dictionary( 'paraphrase', [xml.array(xml.string('value'), alias='values')]) corpus_processor = xml.dictionary( 'corpus', [xml.array(paraphrase_processor, alias='paraphrases')]) self.data_processor = xml.dictionary( 'data', [xml.array(corpus_processor, alias='corpus')])
def test_array_serialize_nested(): """Tests serializing nested arrays""" value = { 'date': '3-21', 'data-points': [ 21.1, 1897.17, 13.1, ] } processor = xml.dictionary('root', [ xml.string('date'), xml.array(xml.floating_point('value'), nested='data-points') ]) expected = strip_xml(""" <root> <date>3-21</date> <data-points> <value>21.1</value> <value>1897.17</value> <value>13.1</value> </data-points> </root> """) actual = xml.serialize_to_string(processor, value) assert expected == actual
def test_array_serialize_omit_empty_present(): """Seralizes a non-empty array with the omit_empty option""" value = { 'message': 'Hello', 'data': [3, 17], } processor = xml.dictionary('root', [ xml.string('message'), xml.array(xml.integer('value', required=False), nested='data', omit_empty=True) ]) expected = strip_xml(""" <root> <message>Hello</message> <data> <value>3</value> <value>17</value> </data> </root> """) actual = xml.serialize_to_string(processor, value) assert expected == actual
def test_parse_array_optional_present(): """Parse optional array that is present""" xml_string = """ <root> <message>Hello, World!</message> <value>45</value> <value>908</value> </root> """ values_array = xml.array(xml.integer('value', required=False), alias='numbers') processor = xml.dictionary('root', [ xml.string('message'), values_array, ]) expected = { 'message': 'Hello, World!', 'numbers': [45, 908], } actual = xml.parse_from_string(processor, xml_string) assert expected == actual
def _collection_to_games(self, data): def after_status_hook(_, status): return [tag for tag, value in status.items() if value == "1"] game_in_collection_processor = xml.dictionary( "items", [ xml.array( xml.dictionary('item', [ xml.integer(".", attribute="objectid", alias="id"), xml.string("name"), xml.string("thumbnail", required=False, alias="image"), xml.string("version/item/thumbnail", required=False, alias="image_version"), xml.dictionary( "status", [ xml.string(".", attribute="fortrade"), xml.string(".", attribute="own"), xml.string(".", attribute="preordered"), xml.string(".", attribute="prevowned"), xml.string(".", attribute="want"), xml.string(".", attribute="wanttobuy"), xml.string(".", attribute="wanttoplay"), xml.string(".", attribute="wishlist"), ], alias='tags', hooks=xml.Hooks(after_parse=after_status_hook)), xml.integer("numplays"), ], required=False, alias="items"), ) ]) collection = xml.parse_from_string(game_in_collection_processor, data) collection = collection["items"] return collection
def test_parse_array_nested(): """Parse nested array""" xml_string = """ <root> <message>Hello, World!</message> <numbers> <number>1</number> <number>2</number> </numbers> </root> """ numbers_array = xml.array(xml.integer('number'), nested='numbers') processor = xml.dictionary('root', [ xml.string('message'), numbers_array, ]) expected = { 'message': 'Hello, World!', 'numbers': [1, 2], } actual = xml.parse_from_string(processor, xml_string) assert expected == actual
def get(self): med_processor = xml.dictionary('response', [ xml.dictionary('header', [ xml.string('resultCode'), xml.string('resultMsg') ]), xml.dictionary('body', [ xml.integer('numOfRows'), xml.integer('pageNo'), xml.integer('totalCount'), xml.dictionary('items', [ xml.array(xml.dictionary('item', [ xml.string('INGR_ENG_NAME'), xml.string('INGR_KOR_NAME'), xml.string('ITEM_NAME_ENG'), xml.string('ITEM_NAME_KOR'), xml.string('SELLING_CORP'), xml.string('DOSAGE_FORM'), xml.string('STRENGTH'), xml.string('GROUPING_NO'), xml.string('PMS_EXP_DATE'), xml.string('KOR_SUIT_YN') ])) ]) ]) ]) med_api = requests.get('http://apis.data.go.kr/1470000/' 'MdcinPatentInfoService/' 'getMdcinPatentInfoList?' 'serviceKey=j1p%2FEIuaPbMKsRuWzOMygNZKwyo2LYZzAWWBwZwxFLc%2BTzuRHN8ROyeJYje%2FPEvs7Hsp6OCVK1fQFt5UcaTocA%3D%3D&' 'pageNo=1&startPage=1&numOfRows=100&pageSize=100') med_xml = med_api.text med_dict = xml.parse_from_string(med_processor, med_xml) items = med_dict['body']['items']['item'] return render_template(self.template, items=items)
class TestSlashPrimitiveInNestedRootArray(_ProcessorTestCase): """Process with a slash to a primitive value in an array""" xml_string = strip_xml(""" <people> <person> <demographics> <age>23</age> </demographics> </person> <person> <demographics> <age>27</age> </demographics> </person> <person> <demographics> <age>31</age> </demographics> </person> </people> """) value = [23, 27, 31] processor = xml.array(xml.integer('person/demographics/age', alias='age'), nested='people')
class TestSlashPrimitiveInNestedArray(_ProcessorTestCase): """Process with a slash to a primitive value in an array""" xml_string = strip_xml(""" <dataset> <source>Census</source> <people> <person> <demographics> <age>23</age> </demographics> </person> <person> <demographics> <age>27</age> </demographics> </person> <person> <demographics> <age>31</age> </demographics> </person> </people> </dataset> """) value = {'source': 'Census', 'ages': [23, 27, 31]} processor = xml.dictionary('dataset', [ xml.string('source'), xml.array(xml.integer('person/demographics/age', alias='age'), nested='people', alias='ages') ])
def test_parse_array_nested_empty_optional(): """Parse nested empty array""" xml_string = """ <root> <message>Hello, World!</message> <numbers /> </root> """ numbers_array = xml.array(xml.integer('number', required=False), nested='numbers') processor = xml.dictionary('root', [ xml.string('message'), numbers_array, ]) expected = { 'message': 'Hello, World!', 'numbers': [], } actual = xml.parse_from_string(processor, xml_string) assert expected == actual
def test_array_element_dictionary(self): """Apply a transform to a dictionary in an array""" xml_string = strip_xml(""" <results> <data> <a>17</a> <b>42</b> <c>23</c> </data> <data> <a>32</a> <b>2</b> <c>15</c> </data> </results> """) value = [ [ ('a', 17), ('b', 42), ('c', 23), ], [ ('a', 32), ('b', 2), ('c', 15), ], ] processor = xml.array(self._dict_processor, nested='results') _transform_test_case_run(processor, value, xml_string)
def test_array_serialize_aggregate(): """Serialize an array of aggregate values""" value = { 'people': [{ 'name': 'Bob', 'age': 27 }, { 'name': 'Jane', 'age': 25 }] } processor = xml.dictionary('root', [ xml.array(xml.dictionary( 'person', [xml.string('name'), xml.integer('age')]), alias='people') ]) expected = strip_xml(""" <root> <person> <name>Bob</name> <age>27</age> </person> <person> <name>Jane</name> <age>25</age> </person> </root> """) actual = xml.serialize_to_string(processor, value) assert expected == actual
def test_named_tuple_serialize(): """Serialize a namedtuple value""" value = Author(name='Robert A. Heinlein', books=[ Book(title='Starship Troopers', year_published=1959), Book(title='Stranger in a Strange Land', year_published=1961) ]) processor = xml.named_tuple('author', Author, [ xml.string('name'), xml.array(xml.named_tuple('book', Book, [ xml.string('title'), xml.integer('year-published', alias='year_published') ]), alias='books') ]) expected = strip_xml(""" <author> <name>Robert A. Heinlein</name> <book> <title>Starship Troopers</title> <year-published>1959</year-published> </book> <book> <title>Stranger in a Strange Land</title> <year-published>1961</year-published> </book> </author> """) actual = xml.serialize_to_string(processor, value) assert expected == actual
def test_user_object_serialize_array(): """Serializes an array of user objects""" value = [ Person().set_values(name='Bob', age=33), Person().set_values(name='Jan', age=24), Person().set_values(name='Tom', age=29) ] processor = xml.array(xml.user_object( 'person', Person, [xml.string('name'), xml.integer('age')]), nested='people') expected = strip_xml(""" <people> <person> <name>Bob</name> <age>33</age> </person> <person> <name>Jan</name> <age>24</age> </person> <person> <name>Tom</name> <age>29</age> </person> </people> """) actual = xml.serialize_to_string(processor, value) assert expected == actual
def test_user_object_serialize_nested(): """Serializes a nested user object""" value = { 'position': 'quarterback', 'person': Person().set_values(name='Bob', pets=['Fluffy', 'Spots']) } processor = xml.dictionary('root', [ xml.string('position'), xml.user_object('person', Person, [ xml.string('name'), xml.array(xml.string('pet'), alias='pets'), ]) ]) expected = strip_xml(""" <root> <position>quarterback</position> <person> <name>Bob</name> <pet>Fluffy</pet> <pet>Spots</pet> </person> </root> """) actual = xml.serialize_to_string(processor, value) assert expected == actual
def __init__(self): self.processor = xml.user_object( "annotation", Annotation, [ xml.user_object("size", Size, [ xml.integer("width"), xml.integer("height"), ]), xml.array( xml.user_object( "object", Object, [ xml.string("name"), xml.user_object( "bndbox", Box, [ xml.floating_point("xmin"), xml.floating_point("ymin"), xml.floating_point("xmax"), xml.floating_point("ymax"), ], alias="box" ) ] ), alias="objects" ), xml.string("filename") ] )
def test_user_object_parse_nested(): """Parse a user object as a nested element in the document""" xml_string = """ <root> <position>quarterback</position> <person> <name>Bob</name> <pet>Fluffy</pet> <pet>Spots</pet> </person> </root> """ processor = xml.dictionary('root', [ xml.string('position'), xml.user_object('person', Person, [ xml.string('name'), xml.array(xml.string('pet'), alias='pets'), ]) ]) expected = { 'position': 'quarterback', 'person': Person().set_values(name='Bob', pets=['Fluffy', 'Spots']) } actual = xml.parse_from_string(processor, xml_string) assert expected == actual
def test_non_root_array(self): """Transform array values for non-root arrays""" xml_string = strip_xml(""" <data> <name>Dataset 1</name> <value key="a">17</value> <value key="b">42</value> <value key="c">37</value> </data> """) value = { 'name': 'Dataset 1', 'values': OrderedDict([ ('a', 17), ('b', 42), ('c', 37), ]), } processor = xml.dictionary('data', [ xml.string('name'), xml.array(self._item_processor, alias='values', hooks=self._hooks) ]) _transform_test_case_run(processor, value, xml_string)
class TestSlashFromRootArray(_ProcessorTestCase): """Process with a slash starting from the root element""" xml_string = strip_xml(""" <locations> <cities> <city name="Kansas City" state="MO" /> <city name="Lincoln" state="NE" /> <city name="Salt Lake City" state="UT" /> </cities> </locations> """) value = [{ 'name': 'Kansas City', 'state': 'MO' }, { 'name': 'Lincoln', 'state': 'NE' }, { 'name': 'Salt Lake City', 'state': 'UT' }] processor = xml.array(xml.dictionary('city', [ xml.string('.', attribute='name'), xml.string('.', attribute='state'), ]), nested='locations/cities', alias='cities')
def test_primitive_transform_array_element(): """Transform a primitive value that is an array element""" xml_string = strip_xml(""" <data> <value>3</value> <value>7</value> <value>16</value> </data> """) value = [ 6, 14, 32, ] def _after_parse(_, x): return int(x * 2) def _before_serialize(_, x): return int(x / 2) hooks = xml.Hooks(after_parse=_after_parse, before_serialize=_before_serialize) processor = xml.array(xml.integer('value', hooks=hooks), nested='data') _transform_test_case_run(processor, value, xml_string)
def test_parse_array_embedded(): """Parse array embedded within its parent element""" xml_string = """ <root> <message>Hello, World!</message> <value>21</value> <value>17</value> <value>90</value> <value>6</value> </root> """ values_array = xml.array(xml.integer('value')) processor = xml.dictionary('root', [ xml.string('message'), values_array, ]) expected = { 'message': 'Hello, World!', 'value': [21, 17, 90, 6], } actual = xml.parse_from_string(processor, xml_string) assert expected == actual
def test_parse_array_embedded_aliased(): """Parse array embedded within its parent element""" xml_string = """ <root> <message>Goodbye, World!</message> <value>765</value> <value>3456</value> </root> """ values_array = xml.array(xml.integer('value'), alias='numbers') processor = xml.dictionary('root', [ xml.string('message'), values_array, ]) expected = { 'message': 'Goodbye, World!', 'numbers': [765, 3456], } actual = xml.parse_from_string(processor, xml_string) assert expected == actual
def test_array_serialize_omit_empty_required(): """Seralizes an array with the omit_empty option""" with pytest.warns(UserWarning): # Should get a warning when specifying omit_empty for required arrays xml.dictionary('root', [ xml.string('message'), xml.array(xml.integer('value'), nested='data', omit_empty=True) ])
def test_array_serialize_missing_root(): """Serialize a missing array""" value = [] processor = xml.array(xml.integer('value'), nested='data') with pytest.raises(xml.MissingValue): xml.serialize_to_string(processor, value)
def test_array_serialize_root_not_nested(): """Serialize an array that is the root""" value = [3.14, 13.7, 6.22] processor = xml.array(xml.floating_point('constant')) with pytest.raises(xml.InvalidRootProcessor): xml.serialize_to_string(processor, value)
class TestSlashArrayOfArrays(_ProcessorTestCase): """Process with slashes to arrays of arrays""" xml_string = strip_xml(""" <root> <data> <experiments> <experiment> <results> <datapoints> <datapoint> <value>3</value> </datapoint> <datapoint> <value>1</value> </datapoint> <datapoint> <value>5</value> </datapoint> </datapoints> </results> </experiment> <experiment> <results> <datapoints> <datapoint> <value>49</value> </datapoint> <datapoint> <value>42</value> </datapoint> </datapoints> </results> </experiment> </experiments> </data> </root> """) value = [[3, 1, 5], [49, 42]] processor = xml.array(xml.array(xml.integer('datapoint/value'), nested='experiment/results/datapoints'), nested='root/data/experiments')
def test_array_of_arrays(self): """Transform array values for a nested array""" xml_string = strip_xml(""" <data> <name>Dataset 1</name> <values> <value key="a">17</value> <value key="b">42</value> <value key="c">37</value> </values> <values> <value key="x">34</value> <value key="y">4</value> <value key="z">58</value> </values> </data> """) value = { 'name': 'Dataset 1', 'values': [ OrderedDict([ ('a', 17), ('b', 42), ('c', 37), ]), OrderedDict([ ('x', 34), ('y', 4), ('z', 58), ]) ], } processor = xml.dictionary('data', [ xml.string('name'), xml.array( xml.array(self._item_processor, nested='values', hooks=self._hooks), ) ]) _transform_test_case_run(processor, value, xml_string)
def test_array_serialize_missing(): """Serialize a missing array""" value = {'message': 'Hello', 'data': []} processor = xml.dictionary( 'root', [xml.string('message'), xml.array(xml.integer('value'), alias='data')]) with pytest.raises(xml.MissingValue): xml.serialize_to_string(processor, value)