Перейти к содержимому

Фотография

Парсинг XML


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 8

#1 Artem26

Artem26

    Новый участник

  • Members
  • Pip
  • 15 сообщений
  • ФИО:Варнавский Артем Геннадьевич

Отправлено 15 января 2018 - 19:52

Всем привет.

Во время теста отправляется запрос на веб-сервис, соответственно отправляется XML с параметрами. С помощью парсера XML разбивается на теги и укладывается в таблицу в базу данных ORACLE. Я занимаюсь автотестированием, тесты на основе ruby/selenium/cucumber. Занимаюсь автотестированием недавно, поэтому знаний мало. Сотрудник из другого отдела занимался разработкой парсинга и прислал следующее сообщение: 

 

--- Запуск процедуры парсинга

BEGIN

  Start_Parse_Use('test', 'setting parse', 'current date - 1' ...и еще несколько параметров)

END

 

Моя задача в автотестах проверить, что этот парсинг работает. Но не представляю как.  Так вот хотел узнать куда прописывается этот код из сообщения (в oracle, код в атотестах, куда-то еще..). Просто впервые с таким столкнулся и не представляю что делать и с чего начать.

 

Извините, если криво объяснил. Заранее спасибо.


  • 0

#2 BadMF

BadMF

    Специалист

  • Members
  • PipPipPipPipPip
  • 809 сообщений
  • ФИО:Dmitry Petrov

Отправлено 16 января 2018 - 06:17

PL SQL Developer используете?

 

ну и прежде всего вам надо разобраться, что конкретно вы тестируете, вёбсервис или процедуру.


  • 0

#3 Little_CJIOH

Little_CJIOH

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 515 сообщений
  • ФИО:Власкин Павел
  • Город:Санкт-Петербург


Отправлено 16 января 2018 - 07:52

Вам прислали образец вызова PL/SQL метода. Хотят от вас, насколько я понимаю, автотестов на этот метод. Учитывая, что у вас ruby, вам нужен gem ruby-plsql https://github.com/rsim/ruby-plsql


PS: Если это Петер Сервис, то у вас есть приличные курсы по PL/SQL, запишитесь на базовый. И поройте конфлюенс, там была статья про выбор инструментов для unit-тестирования pl/sql кода, соответственно там есть и примеры на ruby-plsql и имена людей все это пробовавших и обсуждавших.
PPS: ну и просто гугление "ruby pl sql unit testing" дает пару статей с примерами.
  • 0

#4 SergeyQA

SergeyQA

    Новый участник

  • Members
  • Pip
  • 23 сообщений
  • ФИО:Пронякин Сергей
  • Город:Москва

Отправлено 07 февраля 2018 - 14:31

Всем привет! Очень удачно сразу попалась тема парсинга xml)
У меня такой вопрос к коллегам по Python и библиотекам парсинга XML. 
Потребовалось написать скрипт, который проходится по файлу и сравнивает две цены у всех товаров - новую и старую (price и oldprice). Моя задача понять, что эти цены  отличаются минимум на 5%. Если отличие меньше, то это ошибка, потому что тег oldprice, в таком случае, выводиться в фид не должен.
Порылся на просторах интернета на тему библиотек xml питона. Приглянулась стандартная xml.minidom.
Что сделал. Я смог получить атрибут цены и получил два списка каждой цены.
Но элементы этих списков нельзя сравнивать, т.к. oldprice встречается не у каждого товара (примерно у трети товаров).
То есть, по хорошему, мне нужно проверять для каждого товара, наличие в нем дочернего товара oldprice. И если таковой имеется, то сравнить цену  price и oldprice (или создать два списка и потом их сравнить поэлементно).

Я застрял на том, то не знаю как мне понять, есть ли тег oldprice в <offer></offer>. Как можно это реализовать? Есть какие-то методы, которые выдают вложенные теги? Или типа того..
Буду рад любым ответам, но хорошо бы найти решение в рамках одной библиотеки, которую я использую.

Пример XML:
 

<offer available="true" id="580">
        <url></url>
        <oldprice>13870.00</oldprice>
        <price>13801.00</price>
        <currencyId>RUR</currencyId>
        <categoryId type="Own">14102</categoryId>
        <picture></picture>
        <delivery>true</delivery>
        <local_delivery_cost>650</local_delivery_cost>
        <param name="Условия доставки">A</param>
        <name>Бассейн каркасный INTEX 56942</name>
        <description>&amp;nbsp;Реальный цвет может отличаться от представленного на сайте, ввиду различных настроек монитора.</description>
        <vendor></vendor>
        <delivery-condition>A</delivery-condition>
        <country_of_origin>Китай</country_of_origin>
      </offer>
      <offer available="true" id="585">
        <url></url>
        <price>453.00</price>
        <currencyId>RUR</currencyId>
        <categoryId type="Own">14102</categoryId>
        <picture></picture>
        <delivery>true</delivery>
        <local_delivery_cost>650</local_delivery_cost>
        <param name="Условия доставки">A</param>
        <name>Тент для бассейна INTEX 366*366см</name>
        <description>Защитное покрытие для каркасного бассейна 366х25см. Материалы: полимерные материалы. Реальный цвет может отличаться от представленного на сайте, ввиду различных настроек монитора.</description>
        <vendor></vendor>
        <delivery-condition>A</delivery-condition>
        <country_of_origin>Китай</country_of_origin>
      </offer>

Пример моего кода:
 

from xml.dom import minidom
xml_path = minidom.parse('../exemple.xml')

price_list = xml_path.getElementsByTagName('price') #получаю словарь из price
price_items_list = []
for price in price_list:
    price_items_list.append(price.childNodes[0].nodeValue) #добавляю в изначально пустой список значения тега price

oldprice_list = xml_path.getElementsByTagName('oldprice')
oldprise_item_list = []
for oldprice1 in oldprice_list:
    oldprise_item_list.append(oldprice1.childNodes[0].nodeValue)

print(price_items_list) #['13801.00', '453.00', '621.00', '1561.00', '117.00', '14701.00',...] 
print(oldprise_item_list) #['13801.00', '453.00', '600.00', '1561.00', '2500.00', '14701.00',...]





  • 0

#5 Little_CJIOH

Little_CJIOH

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 515 сообщений
  • ФИО:Власкин Павел
  • Город:Санкт-Петербург


Отправлено 07 февраля 2018 - 17:16

Идеологически, вам надо вычленять список офферов, из него дропать все что не имеет oldprice и с тем что осталось уже работать.
  • 0

#6 SergeyQA

SergeyQA

    Новый участник

  • Members
  • Pip
  • 23 сообщений
  • ФИО:Пронякин Сергей
  • Город:Москва

Отправлено 07 февраля 2018 - 19:57

Идеологически, вам надо вычленять список офферов, из него дропать все что не имеет oldprice и с тем что осталось уже работать.

Да, в том и вопрос. Я не знаю как сделать проверку на наличие тега oldprice в теге offer. Технически не понимаю как это сделать. То есть типа как пройтись циклом по списку надо, но только для дочерних тегов тега offer.


         
    


  • 0

#7 baxatob

baxatob

    Опытный участник

  • Members
  • PipPipPipPip
  • 258 сообщений
  • ФИО:Юрий
  • Город:Riga

Отправлено 07 февраля 2018 - 20:05

minidom весьма прожорливая до памяти библиотека и, имхо, не очень удобная. Попробуйте lxml

Обойдите дерево тэгов, если внутри корневых тэгов встречается тэг oldprice, ищите там price и делайте нужную проверку.


  • 0

#8 SergeyQA

SergeyQA

    Новый участник

  • Members
  • Pip
  • 23 сообщений
  • ФИО:Пронякин Сергей
  • Город:Москва

Отправлено 08 февраля 2018 - 12:29

minidom весьма прожорливая до памяти библиотека и, имхо, не очень удобная. Попробуйте lxml

Обойдите дерево тэгов, если внутри корневых тэгов встречается тэг oldprice, ищите там price и делайте нужную проверку.

Спасибо, посмотрю в эту сторону!


  • 0

#9 SergeyQA

SergeyQA

    Новый участник

  • Members
  • Pip
  • 23 сообщений
  • ФИО:Пронякин Сергей
  • Город:Москва

Отправлено 09 февраля 2018 - 15:06

Ребят, всем спасибо за помощь!
Получилось. Использовал lxml библиотеку. Потратил полдня, но добился того результата, которого хотел.
Вот что вышло:

# -*- coding: utf-8 -*-
from lxml import etree


file_msk_path = open('D:\Download\makecont_0.xml', 'rb').read()
def parseXML(xmlFile):
    """
    Парсинг XML
    """
    root = etree.fromstring(file_msk_path)
    tag_offer = root.findall('.//offer')

    #Поиск дочернего тега oldprice в родительском теге offer
    for child in tag_offer:
        for i in child.getchildren():
            if i.tag == 'oldprice' in i.tag:  # Если в offer есть тег oldprice,
                price = float(i.text)
                oldprice = float(child.getchildren()[1].text)
                sales = (price/oldprice)*100 - 100  # то сравнивать значение тега price и oldprice (отношение в %)
                if sales < 5:
                    print('Offer ID: ' + child.get('id'), '=>', 'Новая цена', i.text,', ',
                          'Старая цена', child.getchildren()[1].text, ', ''Скидка: ', str(round(sales, 1)) + "%")

if __name__ == "__main__":
        parseXML(file_msk_path)

Вывод:
 

Offer ID: 15926 => Новая цена 13100.00 ,  Старая цена 12980.00 , Скидка:  0.9%
Offer ID: 15970 => Новая цена 400.00 ,  Старая цена 390.00 , Скидка:  2.6%
Offer ID: 16000 => Новая цена 1040.00 ,  Старая цена 1020.00 , Скидка:  2.0%
Offer ID: 25748 => Новая цена 2535.00 ,  Старая цена 2449.00 , Скидка:  3.5%

  • 1


Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных