Skocz do zawartości

Edycji XML w Python


Recommended Posts

Witam
Uczę się Pythona (używam wersji 3) i chciałem napisać w ramach nauki prosty program które dodaje przedmioty do sklepu opartego PrestaShop. Udało mi się napisać koślawe GUI w Qt jednak problem mam z komunikacją a dokładnie jak dodać przedmioty. Dokumentacja sklepu jest dla mnie mało zrozumiała(wiem głównie że mam używać REST).

Na podstawie przykładowych produktów widzę że XML ma formę:

<prestashop>
<product>
<id>9</id>
<id_manufacturer>0</id_manufacturer>
<id_supplier>0</id_supplier> 
...

Pobrałem w Pythonie puste drzewo z API sklepu bazują na przykładach z internetu. Zrobiłem to taką funkcją:

    def request(self, url, key, POST):
        username = 'kluczyk'
        password = ''
        api_root = 'http://192.168.1.43/api/'
        url = api_root + url
        passman = urllib.request.HTTPPasswordMgrWithDefaultRealm()
        passman.add_password(None, api_root, username, password)
        authhandler = urllib.request.HTTPBasicAuthHandler(passman)
        opener = urllib.request.build_opener(authhandler)
        urllib.request.install_opener(opener)
        

        params = urllib.parse.urlencode(POST)
        response = urllib.request.urlopen(url).read()
        
        return response

Pobiera on bez problemu plik XML i potem parsuję go tą instrukcją:

empty_xml = ET.fromstring(out)

 

Mam dwa pytania:

1. Jak do pustego drzewa XML włożyć jakieś dane gdy znam nagłówki(podejrzewam że nie jest to poprawna nazwa)? Czyli chcę wpisać np. do id_manufacturer liczbę tak jak w przykładowym pliku. Przeglądałem dokumentacja Pythona ale są tak przykłady na podstawie pętli a nie wydaje mi się to dobre rozwiązanie.

2. Jak w Pythonie przesłać ten dokument na serwer zgodnie z standardem REST? Próbowałem coś kombinować w tej funkcje request ale nie wiem czy to dobra droga. Niestety większość gotowców jest pod 2.7 a myślę że lepiej się już uczyć w serii 3.

 

Z góry dziękuję za pomoc.

Edytowane przez portals
Link to post
Share on other sites

1. Jak chcesz modyfikować tego XMLa to chyba łatwiej będzie użyć minidom.

2. Nie chce mi się wgłębiać w dokumentację tego sklepu, ale w standardowym rescie puszcza po prostu zapytanie POST z dołączonym XMLem jako data.

  • Popieram 1
Link to post
Share on other sites

Dziękuję za wskazówkę. Po wielu próbach z minidom i ElementTree udało mi się edytować tego XML.

Niestety nie jest on przyjmowany przez PrestoShop.

Wysyłam samą strukturę bez danych(z danymi jest to samo):

b'<?xml version=\'1.0\' encoding=\'utf8\'?>\n<prestashop>\n<product>\n\t<id />\n\t<id_manufacturer />\n\t<id_supplier />\n\t<id_category_default />\n\t<new />\n\t<cache_default_attribute />\n\t<id_default_image />\n\t<id_default_combination />\n\t<id_tax_rules_group />\n\t<type />\n\t<id_shop_default />\n\t<reference />\n\t<supplier_reference />\n\t<location />\n\t<width />\n\t<height />\n\t<depth />\n\t<weight />\n\t<quantity_discount />\n\t<ean13 />\n\t<upc />\n\t<cache_is_pack />\n\t<cache_has_attachments />\n\t<is_virtual />\n\t<on_sale />\n\t<online_only />\n\t<ecotax />\n\t<minimal_quantity />\n\t<price />\n\t<wholesale_price />\n\t<unity />\n\t<unit_price_ratio />\n\t<additional_shipping_cost />\n\t<customizable />\n\t<text_fields />\n\t<uploadable_files />\n\t<active />\n\t<redirect_type />\n\t<id_product_redirected />\n\t<available_for_order />\n\t<available_date />\n\t<condition />\n\t<show_price />\n\t<indexed />\n\t<visibility />\n\t<advanced_stock_management />\n\t<date_add />\n\t<date_upd />\n\t<meta_description><language id="1" /></meta_description>\n\t<meta_keywords><language id="1" /></meta_keywords>\n\t<meta_title><language id="1" /></meta_title>\n\t<link_rewrite><language id="1">%28nowa%29PS3</language></link_rewrite>\n\t<name><language id="1">(nowa)</language></name>\n\t<description><language id="1" /></description>\n\t<description_short><language id="1" /></description_short>\n\t<available_now><language id="1" /></available_now>\n\t<available_later><language id="1" /></available_later>\n<associations>\n<categories>\n\t<category>\n\t<id />\n\t</category>\n</categories>\n<images>\n\t<image>\n\t<id />\n\t</image>\n</images>\n<combinations>\n\t<combinations>\n\t<id />\n\t</combinations>\n</combinations>\n<product_option_values>\n\t<product_options_values>\n\t<id />\n\t</product_options_values>\n</product_option_values>\n<product_features>\n\t<product_feature>\n\t<id />\n\t<custom />\n\t<id_feature_value />\n\t</product_feature>\n</product_features>\n<tags>\n\t<tag>\n\t<id />\n\t</tag>\n</tags>\n<stock_availables>\n\t<stock_available>\n\t<id />\n\t<id_product_attribute />\n\t</stock_available>\n</stock_availables>\n<accessories>\n\t<product>\n\t<id />\n\t</product>\n</accessories>\n<product_bundle>\n\t<products>\n\t<id />\n\t<quantity />\n\t</products>\n</product_bundle>\n</associations>\n</product>\n</prestashop>'
Dostaje odpowiedz:

b'<?xml version="1.0" encoding="UTF-8"?>\n<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">\n<errors>\n<error>\n<code><![CDATA[127]]></code>\n<message><![CDATA[XML error : String could not be parsed as XML\nXML length : 3379\nOriginal XML : XML=%3C%3Fxml+version%3D%271.0%27+encoding%3D%27utf8%27%3F%3E%0A%3Cprestashop%3E%0A%3Cproduct%3E%0A%09%3Cid+%2F%3E%0A%09%3Cid_manufacturer+%2F%3E%0A%09%3Cid_supplier+%2F%3E%0A%09%3Cid_category_default+%2F%3E%0A%09%3Cnew+%2F%3E%0A%09%3Ccache_default_attribute+%2F%3E%0A%09%3Cid_default_image+%2F%3E%0A%09%3Cid_default_combination+%2F%3E%0A%09%3Cid_tax_rules_group+%2F%3E%0A%09%3Ctype+%2F%3E%0A%09%3Cid_shop_default+%2F%3E%0A%09%3Creference+%2F%3E%0A%09%3Csupplier_reference+%2F%3E%0A%09%3Clocation+%2F%3E%0A%09%3Cwidth+%2F%3E%0A%09%3Cheight+%2F%3E%0A%09%3Cdepth+%2F%3E%0A%09%3Cweight+%2F%3E%0A%09%3Cquantity_discount+%2F%3E%0A%09%3Cean13+%2F%3E%0A%09%3Cupc+%2F%3E%0A%09%3Ccache_is_pack+%2F%3E%0A%09%3Ccache_has_attachments+%2F%3E%0A%09%3Cis_virtual+%2F%3E%0A%09%3Con_sale+%2F%3E%0A%09%3Conline_only+%2F%3E%0A%09%3Cecotax+%2F%3E%0A%09%3Cminimal_quantity+%2F%3E%0A%09%3Cprice+%2F%3E%0A%09%3Cwholesale_price+%2F%3E%0A%09%3Cunity+%2F%3E%0A%09%3Cunit_price_ratio+%2F%3E%0A%09%3Cadditional_shipping_cost+%2F%3E%0A%09%3Ccustomizable+%2F%3E%0A%09%3Ctext_fields+%2F%3E%0A%09%3Cuploadable_files+%2F%3E%0A%09%3Cactive+%2F%3E%0A%09%3Credirect_type+%2F%3E%0A%09%3Cid_product_redirected+%2F%3E%0A%09%3Cavailable_for_order+%2F%3E%0A%09%3Cavailable_date+%2F%3E%0A%09%3Ccondition+%2F%3E%0A%09%3Cshow_price+%2F%3E%0A%09%3Cindexed+%2F%3E%0A%09%3Cvisibility+%2F%3E%0A%09%3Cadvanced_stock_management+%2F%3E%0A%09%3Cdate_add+%2F%3E%0A%09%3Cdate_upd+%2F%3E%0A%09%3Cmeta_description%3E%3Clanguage+id%3D%221%22+%2F%3E%3C%2Fmeta_description%3E%0A%09%3Cmeta_keywords%3E%3Clanguage+id%3D%221%22+%2F%3E%3C%2Fmeta_keywords%3E%0A%09%3Cmeta_title%3E%3Clanguage+id%3D%221%22+%2F%3E%3C%2Fmeta_title%3E%0A%09%3Clink_rewrite%3E%3Clanguage+id%3D%221%22%3E%2528nowa%2529PS3%3C%2Flanguage%3E%3C%2Flink_rewrite%3E%0A%09%3Cname%3E%3Clanguage+id%3D%221%22%3E%28nowa%29%3C%2Flanguage%3E%3C%2Fname%3E%0A%09%3Cdescription%3E%3Clanguage+id%3D%221%22+%2F%3E%3C%2Fdescription%3E%0A%09%3Cdescription_short%3E%3Clanguage+id%3D%221%22+%2F%3E%3C%2Fdescription_short%3E%0A%09%3Cavailable_now%3E%3Clanguage+id%3D%221%22+%2F%3E%3C%2Favailable_now%3E%0A%09%3Cavailable_later%3E%3Clanguage+id%3D%221%22+%2F%3E%3C%2Favailable_later%3E%0A%3Cassociations%3E%0A%3Ccategories%3E%0A%09%3Ccategory%3E%0A%09%3Cid+%2F%3E%0A%09%3C%2Fcategory%3E%0A%3C%2Fcategories%3E%0A%3Cimages%3E%0A%09%3Cimage%3E%0A%09%3Cid+%2F%3E%0A%09%3C%2Fimage%3E%0A%3C%2Fimages%3E%0A%3Ccombinations%3E%0A%09%3Ccombinations%3E%0A%09%3Cid+%2F%3E%0A%09%3C%2Fcombinations%3E%0A%3C%2Fcombinations%3E%0A%3Cproduct_option_values%3E%0A%09%3Cproduct_options_values%3E%0A%09%3Cid+%2F%3E%0A%09%3C%2Fproduct_options_values%3E%0A%3C%2Fproduct_option_values%3E%0A%3Cproduct_features%3E%0A%09%3Cproduct_feature%3E%0A%09%3Cid+%2F%3E%0A%09%3Ccustom+%2F%3E%0A%09%3Cid_feature_value+%2F%3E%0A%09%3C%2Fproduct_feature%3E%0A%3C%2Fproduct_features%3E%0A%3Ctags%3E%0A%09%3Ctag%3E%0A%09%3Cid+%2F%3E%0A%09%3C%2Ftag%3E%0A%3C%2Ftags%3E%0A%3Cstock_availables%3E%0A%09%3Cstock_available%3E%0A%09%3Cid+%2F%3E%0A%09%3Cid_product_attribute+%2F%3E%0A%09%3C%2Fstock_available%3E%0A%3C%2Fstock_availables%3E%0A%3Caccessories%3E%0A%09%3Cproduct%3E%0A%09%3Cid+%2F%3E%0A%09%3C%2Fproduct%3E%0A%3C%2Faccessories%3E%0A%3Cproduct_bundle%3E%0A%09%3Cproducts%3E%0A%09%3Cid+%2F%3E%0A%09%3Cquantity+%2F%3E%0A%09%3C%2Fproducts%3E%0A%3C%2Fproduct_bundle%3E%0A%3C%2Fassociations%3E%0A%3C%2Fproduct%3E%0A%3C%2Fprestashop%3E]]></message>\n</error>\n</errors>\n</prestashop>\n'
Wysyłam dane tak:

...
xml = ET.tostring(xml, encoding='utf8', method='xml')
print(xml)
out = self.request('products', self.api_key.text(), xml)
print (out)
 
def request(self, url, key, POST):
        username = 'kluczyk'
        password = ''
        api_root = 'http://192.168.1.43/api/'
        
        passman = urllib.request.HTTPPasswordMgrWithDefaultRealm()
        passman.add_password(None, api_root, username, password)
        authhandler = urllib.request.HTTPBasicAuthHandler(passman)
        opener = urllib.request.build_opener(authhandler)
        urllib.request.install_opener(opener)
        
        if POST == 0:
            url = api_root + url
            response = urllib.request.urlopen(url).read()
        else:
            url = api_root + url
            params = urllib.parse.urlencode({'XML': POST})
            params = params.encode('utf-8')
            try:
                response = urllib.request.urlopen(url, params).read()
            except HTTPError as e:
                response = e.read()

        
        return response
Będę bardzo wdzięczny za pomoc bo naprawdę spędziłem już wiele godzin przy wydawało by się prostym programie a ciągle nowe problemy. Wydaję mi się że coś nie tak jest z kodowaniem. Edytowane przez portals
Link to post
Share on other sites

Walidator podaje, że Twój XML jest poprawny, ale to nie znaczy, że parser, którego używa Presto jest w 100% zgodny ze specyfikacją XML. Tak na pierwszy rzut oka widzę, że w pierwszym tagu masz apostrofy, a dalej cudzysłowia, Spróbuj zmienić je na cudzysłowia.

  • Popieram 1
Link to post
Share on other sites

Odpowiedz Presto zawiera też mój xml ale widać że zawiera dziwne ciągi znaków. To normalne?
Teraz sprawdziłem i presto używa standardowej klasy php SimpleXMLElement. Raczej odpada że zawiera ona błędy.
EDIT:
Zrobiłem test na prostym skrypcie i był w stanie on odczytać XML.
Spróbowałem wysłać tego xml który dostaje się z API dostałem, ten sam komunikat.
XML:

<?xml version="1.0" encoding="UTF-8"?> <prestashop xmlns:xlink="http://www.w3.org/1999/xlink"> <product> 	<id></id> 	<id_manufacturer></id_manufacturer> 	<id_supplier></id_supplier> 	<id_category_default></id_category_default> 	<new></new> 	<cache_default_attribute></cache_default_attribute> 	<id_default_image></id_default_image> 	<id_default_combination></id_default_combination> 	<id_tax_rules_group></id_tax_rules_group> 	<type></type> 	<id_shop_default></id_shop_default> 	<reference></reference> 	<supplier_reference></supplier_reference> 	<location></location> 	<width></width> 	<height></height> 	<depth></depth> 	<weight></weight> 	<quantity_discount></quantity_discount> 	<ean13></ean13> 	<upc></upc> 	<cache_is_pack></cache_is_pack> 	<cache_has_attachments></cache_has_attachments> 	<is_virtual></is_virtual> 	<on_sale></on_sale> 	<online_only></online_only> 	<ecotax></ecotax> 	<minimal_quantity></minimal_quantity> 	<price></price> 	<wholesale_price></wholesale_price> 	<unity></unity> 	<unit_price_ratio></unit_price_ratio> 	<additional_shipping_cost></additional_shipping_cost> 	<customizable></customizable> 	<text_fields></text_fields> 	<uploadable_files></uploadable_files> 	<active></active> 	<redirect_type></redirect_type> 	<id_product_redirected></id_product_redirected> 	<available_for_order></available_for_order> 	<available_date></available_date> 	<condition></condition> 	<show_price></show_price> 	<indexed></indexed> 	<visibility></visibility> 	<advanced_stock_management></advanced_stock_management> 	<date_add></date_add> 	<date_upd></date_upd> 	<meta_description><language id="1"></language></meta_description> 	<meta_keywords><language id="1"></language></meta_keywords> 	<meta_title><language id="1"></language></meta_title> 	<link_rewrite><language id="1"></language></link_rewrite> 	<name><language id="1"></language></name> 	<description><language id="1"></language></description> 	<description_short><language id="1"></language></description_short> 	<available_now><language id="1"></language></available_now> 	<available_later><language id="1"></language></available_later> <associations> <categories> 	<category> 	<id></id> 	</category> </categories> <images> 	<image> 	<id></id> 	</image> </images> <combinations> 	<combinations> 	<id></id> 	</combinations> </combinations> <product_option_values> 	<product_options_values> 	<id></id> 	</product_options_values> </product_option_values> <product_features> 	<product_feature> 	<id></id> 	<custom></custom> 	<id_feature_value></id_feature_value> 	</product_feature> </product_features> <tags> 	<tag> 	<id></id> 	</tag> </tags> <stock_availables> 	<stock_available> 	<id></id> 	<id_product_attribute></id_product_attribute> 	</stock_available> </stock_availables> <accessories> 	<product> 	<id></id> 	</product> </accessories> <product_bundle> 	<products> 	<id></id> 	<quantity></quantity> 	</products> </product_bundle> </associations> </product> </prestashop>
Edytowane przez portals
Link to post
Share on other sites

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Odpowiedz w tym wątku...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...