Различия
Здесь показаны различия между двумя версиями данной страницы.
| Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
|
fullcircle:36:python_ч_10 [2010/08/07 21:11] |
fullcircle:36:python_ч_10 [2011/02/20 16:27] (текущий) |
||
|---|---|---|---|
| Строка 3: | Строка 3: | ||
| //Автор — Грэг Валтерс (Greg Walters)// | //Автор — Грэг Валтерс (Greg Walters)// | ||
| </style> | </style> | ||
| + | |||
| - [[..:27:python_ч_1|Программа на Python — часть 1]] | - [[..:27:python_ч_1|Программа на Python — часть 1]] | ||
| Строка 15: | Строка 16: | ||
| - [[..:36:python_ч_10|Программа на Python — часть 10]] | - [[..:36:python_ч_10|Программа на Python — часть 10]] | ||
| - [[..:37:python_ч_11|Программа на Python — часть 11]] | - [[..:37:python_ч_11|Программа на Python — часть 11]] | ||
| + | - [[..:38:python_ч_12|Программа на Python — часть 12]] | ||
| + | - [[..:39:python_ч_13|Программа на Python — часть 13]] | ||
| + | - [[..:40:python_ч_14|Программа на Python — часть 14]] | ||
| Возможно, вы слышали об XML, однако можете и не знать, что это такое. В этом месяце нашу лекцию мы посвятим XML. Цели лекции: | Возможно, вы слышали об XML, однако можете и не знать, что это такое. В этом месяце нашу лекцию мы посвятим XML. Цели лекции: | ||
| Строка 38: | Строка 42: | ||
| <root><node1> Данные… </node1><node2 attribute=«something»> Данные Узла 2 </node2><node3><node3sub1>ещё данные</node3sub1></node3></root> | <root><node1> Данные… </node1><node2 attribute=«something»> Данные Узла 2 </node2><node3><node3sub1>ещё данные</node3sub1></node3></root> | ||
| - | Тэги внутри угловых скобок «< >» отвечают некоторым правилам. Они должны состоять из одного слова. Каждому открывающему тэгу (например, <root>) должен соответствовать закрывающий, начинающийся с «/». Кроме того, тэги чувствительны к регистру: <node>, <Node>, <NODE> и <NodE> – различны, и к каждому из них должен быть свой закрывающий тэг. Наименования тэгов могут содержать буквы, цифры и другие символы, но не могут начинаться с цифры или знака препинания. Избегайте знаков «-», «.», «:» в именах тэгов, так как некоторые программы могут рассматривать их как команды или свойства объекта. Помимо этого, запятые зарезервированы для некоторых других целей. Тэги также можно называть элементами. | + | Тэги внутри угловых скобок **«< >»** отвечают некоторым правилам. Они должны состоять из одного слова. Каждому открывающему тэгу (например, <root>) должен соответствовать закрывающий, начинающийся с **«/»**. **Кроме того, тэги чувствительны к регистру: <node>, <Node>, <NODE> и <NodE> – различны**, и к каждому из них должен быть свой закрывающий тэг. Наименования тэгов могут содержать буквы, цифры и другие символы, но не могут начинаться с цифры или знака препинания. Избегайте знаков «-», «.», «:» в именах тэгов, так как некоторые программы могут рассматривать их как команды или свойства объекта. Помимо этого, запятые зарезервированы для некоторых других целей. Тэги также можно называть элементами. |
| Каждый XML-файл – это древовидная структура, начинающаяся с корня и ответвляющаяся от него. Он ДОЛЖЕН иметь корневой элемент – родитель для всех других элементов в файле. Вернёмся к нашему примеру. От корня отходят три дочерних элемента: node1, node2 и node3. Дочерние элементы имеют общий корень, а node3 является родителем для node3sub1. | Каждый XML-файл – это древовидная структура, начинающаяся с корня и ответвляющаяся от него. Он ДОЛЖЕН иметь корневой элемент – родитель для всех других элементов в файле. Вернёмся к нашему примеру. От корня отходят три дочерних элемента: node1, node2 и node3. Дочерние элементы имеют общий корень, а node3 является родителем для node3sub1. | ||
| Строка 48: | Строка 52: | ||
| Имеется корневой элемент «people», содержащий два дочерних – «person». Каждый элемент «person» содержит 6 дочерних элементов: «firstname», «lastname», «gender», «address», «city» и «state». На первый взгляд, XML-файл можно рассматривать как базу данных (вспомните несколько последних лекций), и это верное предположение. Некоторые приложения используют XML-файлы как простую структуру базы данных. Не составит труда написать программу для чтения XML-файла. Она должна открыть файл, прочитать его построчно и, в зависимости от элемента, использовать заключённые в нём данные, а затем закрыть файл. Однако есть и более эффективные способы. | Имеется корневой элемент «people», содержащий два дочерних – «person». Каждый элемент «person» содержит 6 дочерних элементов: «firstname», «lastname», «gender», «address», «city» и «state». На первый взгляд, XML-файл можно рассматривать как базу данных (вспомните несколько последних лекций), и это верное предположение. Некоторые приложения используют XML-файлы как простую структуру базы данных. Не составит труда написать программу для чтения XML-файла. Она должна открыть файл, прочитать его построчно и, в зависимости от элемента, использовать заключённые в нём данные, а затем закрыть файл. Однако есть и более эффективные способы. | ||
| - | В следующем примере мы воспользуемся модулем библиотеки под названием ElementTree. Его можно получить непосредственно из Synaptic, установив python-elementtree. Однако я предпочитаю устанавливать с сайта ElementTree (http://effbot.org/ downloads/#elementtree) и непосредственно загружать файл-исходник (elementtree-1.2.6-20050316.tar.gz). После загрузки я с помощью менеджера пакетов извлекаю его во временную папку. Затем в этой папке выполняю «sudo python setup.py install». Эта команда помещает файлы в общую папку python, поэтому в дальнейшем у меня есть возможность использовать модуль и в python 2.5, и в 2.6. Итак, приступим к работе! Создайте папку, которая будет содержать код этого месяца, скопируйте приведённые выше данные в XML-формате в ваш любимый текстовой редактор и сохраните их в эту папку под именем «xmlsample1.xml». | + | В следующем примере мы воспользуемся модулем библиотеки под названием ElementTree. Его можно получить непосредственно из Synaptic, установив python-elementtree. Однако я предпочитаю устанавливать с сайта ElementTree (http://effbot.org/downloads/#elementtree) и непосредственно загружать файл-исходник (elementtree-1.2.6-20050316.tar.gz). После загрузки я с помощью менеджера пакетов извлекаю его во временную папку. Затем в этой папке выполняю «sudo python setup.py install». Эта команда помещает файлы в общую папку python, поэтому в дальнейшем у меня есть возможность использовать модуль и в python 2.5, и в 2.6. Итак, приступим к работе! Создайте папку, которая будет содержать код этого месяца, скопируйте приведённые выше данные в XML-формате в ваш любимый текстовой редактор и сохраните их в эту папку под именем «xmlsample1.xml». |
| Поговорим о нашем коде. В первую очередь хочется протестировать установленный модуль ElementTree. | Поговорим о нашем коде. В первую очередь хочется протестировать установленный модуль ElementTree. | ||
| - | import elementtree.ElementTree as ET | + | <code>import elementtree.ElementTree as ET |
| tree = ET.parse('xmlsample1.xml') | tree = ET.parse('xmlsample1.xml') | ||
| - | ET.dump(tree) | + | ET.dump(tree)</code> |
| Запустив эту программу, мы получим нечто похожее на то, что представлено ниже. | Запустив эту программу, мы получим нечто похожее на то, что представлено ниже. | ||
| Строка 64: | Строка 68: | ||
| Теперь заменим наш код на следующий: | Теперь заменим наш код на следующий: | ||
| - | import elementtree.ElementTree as ET | + | <code>import elementtree.ElementTree as ET |
| tree = ET.parse('xmlsample1.xml') | tree = ET.parse('xmlsample1.xml') | ||
| Строка 74: | Строка 78: | ||
| for dat in p: | for dat in p: | ||
| - | print "Элемент: %s - Данные: %s" %(dat.tag,dat.text) | + | print "Элемент: %s - Данные: %s" %(dat.tag,dat.text)</code> |
| Запустите код снова. Результат будет таким: | Запустите код снова. Результат будет таким: | ||
| - | /usr/bin/python -u "/home/greg/Documents/articles/xml/reader1.py" | + | **/usr/bin/python -u "/home/greg/Documents/articles/xml/reader1.py"** |
| - | Элемент: firstname - Данные: Саманта | + | * Элемент: firstname - Данные: Саманта |
| - | Элемент: lastname - Данные: Фэроу | + | * Элемент: lastname - Данные: Фэроу |
| - | Элемент: gender - Данные: Женский | + | * Элемент: gender - Данные: Женский |
| - | Элемент: address - Данные: ул. Мэйн, д. 123 | + | * Элемент: address - Данные: ул. Мэйн, д. 123 |
| - | Элемент: city - Данные: Дэнвер | + | * Элемент: city - Данные: Дэнвер |
| - | Элемент: state - Данные: Колорадо | + | * Элемент: state - Данные: Колорадо |
| - | Элемент: firstname - Данные: Стив | + | * Элемент: firstname - Данные: Стив |
| - | Элемент: lastname - Данные: Левон | + | * Элемент: lastname - Данные: Левон |
| - | Элемент: gender - Данные: Мужской | + | * Элемент: gender - Данные: Мужской |
| - | Элемент: address - Данные: Бульвар Арапахо, 332120 | + | * Элемент: address - Данные: Бульвар Арапахо, 332120 |
| - | Элемент: city - Данные: Дэнвер | + | * Элемент: city - Данные: Дэнвер |
| - | Элемент: state - Данные: Колорадо | + | * Элемент: state - Данные: Колорадо |
| Теперь каждая порция данных выводится напротив имени тэга. Эти данные можно легко распечатать. Итак, посмотрим, что делает программа. Модуль ElementTree проанализировал файл и поместил результаты в объект tree. Затем ElementTree нашёл все вхождения тэга person. В нашем примере таких элементов оказалось два, но их могло быть 1 или 1000. Элемент person – дочерний к корневому элементу people. Все данные были разбиты на порции. Затем мы создали простой цикл, перебирающий объекты person. Вложенный в него цикл перебирает данные каждого элемента person, и на экран выводятся результаты, показывающие имя элемента (.tag) и данные (.text). | Теперь каждая порция данных выводится напротив имени тэга. Эти данные можно легко распечатать. Итак, посмотрим, что делает программа. Модуль ElementTree проанализировал файл и поместил результаты в объект tree. Затем ElementTree нашёл все вхождения тэга person. В нашем примере таких элементов оказалось два, но их могло быть 1 или 1000. Элемент person – дочерний к корневому элементу people. Все данные были разбиты на порции. Затем мы создали простой цикл, перебирающий объекты person. Вложенный в него цикл перебирает данные каждого элемента person, и на экран выводятся результаты, показывающие имя элемента (.tag) и данные (.text). | ||
| Строка 105: | Строка 109: | ||
| Первая строка обычно сообщает, что это проверенный XML-файл, её можно проигнорировать. Следующая строка, начинающаяся с «loc», является корневым элементом и содержит атрибуты «version» и «src». Выше я отмечал, что атрибуты иногда используются в файлах. В дальнейшем мы ещё будем иметь дело с ними в этом файле. Корневой элемент тут также может быть проигнорирован. Следующая строка содержит тэг дочернего элемента – маршрутной точки (waypoint). (Маршрутная точка – это место расположения, где можно найти тайник). Из этого элемента можно получить важные сведения: наименование тайника, координаты (долготу и широту), тип тайника и ссылку на интернет-страницу с дополнительной информацией. Элемент с именем содержит кучу полезной информации, но проводить её структурный анализ придётся самостоятельно. Давайте теперь создадим программу для чтения и отображения файла cache.loc, назвав её readacache.py. Начнём с импорта модуля и команд для структурного анализа из предыдущего примера. | Первая строка обычно сообщает, что это проверенный XML-файл, её можно проигнорировать. Следующая строка, начинающаяся с «loc», является корневым элементом и содержит атрибуты «version» и «src». Выше я отмечал, что атрибуты иногда используются в файлах. В дальнейшем мы ещё будем иметь дело с ними в этом файле. Корневой элемент тут также может быть проигнорирован. Следующая строка содержит тэг дочернего элемента – маршрутной точки (waypoint). (Маршрутная точка – это место расположения, где можно найти тайник). Из этого элемента можно получить важные сведения: наименование тайника, координаты (долготу и широту), тип тайника и ссылку на интернет-страницу с дополнительной информацией. Элемент с именем содержит кучу полезной информации, но проводить её структурный анализ придётся самостоятельно. Давайте теперь создадим программу для чтения и отображения файла cache.loc, назвав её readacache.py. Начнём с импорта модуля и команд для структурного анализа из предыдущего примера. | ||
| - | import elementtree.ElementTree as ET | + | <code>import elementtree.ElementTree as ET |
| - | tree = ET.parse('Cache.loc') | + | tree = ET.parse('Cache.loc')</code> |
| Нам необходимо получить только данные, находящиеся внутри тэга waypoint. Для этого мы используем функцию .find внутри модуля ElementTree. Результаты работы будут сохранены в объекте w. | Нам необходимо получить только данные, находящиеся внутри тэга waypoint. Для этого мы используем функцию .find внутри модуля ElementTree. Результаты работы будут сохранены в объекте w. | ||
| - | w = tree.find('.//waypoint') | + | <code>w = tree.find('.//waypoint')</code> |
| Затем нам необходимо просмотреть все данные, для чего используется цикл for. В теле цикла мы ищем элементы name (имя), coord (координаты), type (тип) и link (ссылка). На основании содержащихся в тэге данных, мы извлекаем информацию, чтобы распечатать её в дальнейшем. | Затем нам необходимо просмотреть все данные, для чего используется цикл for. В теле цикла мы ищем элементы name (имя), coord (координаты), type (тип) и link (ссылка). На основании содержащихся в тэге данных, мы извлекаем информацию, чтобы распечатать её в дальнейшем. | ||
| - | for w1 in w: | + | <code>for w1 in w: |
| - | if w1.tag == "name": | + | if w1.tag == "name":</code> |
| Просмотрим, какие данные можно извлечь из тэга name. | Просмотрим, какие данные можно извлечь из тэга name. | ||
| - | + | <code> | |
| - | <name id="N02CAC"><![CDATA[Возьмите Фотографии озера Виноградной лозы, сделанные g_phillips | + | <name id="N02CAC"><![CDATA[Возьмите Фотографии озера |
| + | Виноградной лозы, сделанные g_phillips | ||
| Тайник открыт: не ограничено | Тайник открыт: не ограничено | ||
| Строка 131: | Строка 136: | ||
| Местность: 2.0]]></name> | Местность: 2.0]]></name> | ||
| + | </code> | ||
| Это одна очень длинная строка. Идентификатор id установлен как атрибут. Имя тайника – это часть строки после «CDATA» и до «Тайник открыт:». Мы разделим | Это одна очень длинная строка. Идентификатор id установлен как атрибут. Имя тайника – это часть строки после «CDATA» и до «Тайник открыт:». Мы разделим | ||
| - | строку на несколько более мелких частей. Получить часть строки можно, используя следующий код: | + | строку на несколько более мелких частей. |
| - | + | ||
| - | newstring = oldstring[startposition:endposition] | + | <code>newstring = oldstring[startposition:endposition]</code> |
| Итак, приведенный код можно использовать для извлечения необходимой информации. | Итак, приведенный код можно использовать для извлечения необходимой информации. | ||
| Строка 205: | Строка 208: | ||
| <loc version="1.0" src="NaviCache"> | <loc version="1.0" src="NaviCache"> | ||
| <waypoint> | <waypoint> | ||
| - | <name id="N02CAC"><![CDATA[Take Goofy Pictures at Grapevine Lake by g_phillips | + | <name id="N02CAC"><![CDATA[Take Goofy |
| + | Pictures at Grapevine Lake by g_phillips | ||
| Open Cache: Unrestricted | Open Cache: Unrestricted | ||
| Cache Type: Normal | Cache Type: Normal | ||
| Строка 213: | Строка 217: | ||
| <coord lat="32.9890166666667" lon="-97.0728833333333" /> | <coord lat="32.9890166666667" lon="-97.0728833333333" /> | ||
| <type>Geocache</type> | <type>Geocache</type> | ||
| - | <link text="Cache Details">http://www.navicache.com/cgi-bin/db/displaycache2.pl?CacheID=11436</link> | + | <link |
| + | text="Cache Details"> | ||
| + | http://www.navicache.com/cgi-bin/db/displaycache2.pl | ||
| + | ?CacheID=11436</link> | ||
| </waypoint> | </waypoint> | ||
| </loc> | </loc> | ||
| Строка 221: | Строка 228: | ||
| <code> | <code> | ||
| # Get text of cache name up to the phrase "Open Cache: " | # Get text of cache name up to the phrase "Open Cache: " | ||
| - | CacheName = w1.text[:w1.text.find("Open Cache: ")-1] | + | CacheName = w1.text[:w1.text.find |
| + | ("Open Cache: ")-1] | ||
| # Get the text between "Open Cache: " and "Cache Type: " | # Get the text between "Open Cache: " and "Cache Type: " | ||
| - | OpenCache = w1.text[w1.text.find("Open Cache: ")+12:w1.text.find("Cache Type: ")-1] | + | OpenCache = w1.text[w1.text.find |
| + | ("Open Cache: ")+12:w1.text.find("Cache Type: ")-1] | ||
| # More of the same | # More of the same | ||
| - | CacheType = w1.text[w1.text.find("Cache Type: ")+12:w1.text.find("Cache Size: ")-1] | + | CacheType = w1.text[w1.text.find |
| - | CacheSize = w1.text[w1.text.find("Cache Size: ")+12:w1.text.find("Difficulty: ")-1] | + | ("Cache Type: ")+12:w1.text.find |
| - | Difficulty= w1.text[w1.text.find("Difficulty: ")+12:w1.text.find("Terrain : ")-1] | + | ("Cache Size: ")-1] |
| - | Terrain = w1.text[w1.text.find("Terrain : ")+12:] | + | CacheSize = w1.text[w1.text.find |
| + | ("Cache Size: ")+12:w1.text.find | ||
| + | ("Difficulty: ")-1] | ||
| + | Difficulty= w1.text[w1.text.find | ||
| + | ("Difficulty: ")+12:w1.text.find | ||
| + | ("Terrain : ")-1] | ||
| + | Terrain = w1.text[w1.text.find | ||
| + | ("Terrain : ")+12:] | ||
| </code> | </code> | ||
| Строка 269: | Строка 285: | ||
| if w1.tag == "name": | if w1.tag == "name": | ||
| # Get text of cache name up to the phrase "Open Cache: " | # Get text of cache name up to the phrase "Open Cache: " | ||
| - | CacheName = w1.text[:w1.text.find("Open Cache: ")-1] | + | CacheName = w1.text[:w1.text.find |
| - | # Get the text between "Open Cache: " and "Cache Type: " | + | ("Open Cache: ")-1] |
| - | OpenCache = w1.text[w1.text.find("Open Cache: ")+12:w1.text.find("Cache Type: ")-1] | + | # Get the text between |
| + | "Open Cache: " and "Cache Type: " | ||
| + | OpenCache = w1.text[w1.text.find | ||
| + | ("Open Cache: ")+12:w1.text.find | ||
| + | ("Cache Type: ")-1] | ||
| # More of the same | # More of the same | ||
| - | CacheType = w1.text[w1.text.find("Cache Type: ")+12:w1.text.find("Cache Size: ")-1] | + | CacheType = w1.text[w1.text.find |
| - | CacheSize = w1.text[w1.text.find("Cache Size: ")+12:w1.text.find("Difficulty: ")-1] | + | ("Cache Type: ")+12:w1.text.find |
| - | Difficulty= w1.text[w1.text.find("Difficulty: ")+12:w1.text.find("Terrain : ")-1] | + | ("Cache Size: ")-1] |
| - | Terrain = w1.text[w1.text.find("Terrain : ")+12:] | + | CacheSize = w1.text[w1.text.find |
| + | ("Cache Size: ")+12:w1.text.find | ||
| + | ("Difficulty: ")-1] | ||
| + | Difficulty= w1.text[w1.text.find | ||
| + | ("Difficulty: ")+12:w1.text.find | ||
| + | ("Terrain : ")-1] | ||
| + | Terrain = w1.text[w1.text.find | ||
| + | ("Terrain : ")+12:] | ||
| if w1.keys(): | if w1.keys(): | ||
| for name,value in w1.items(): | for name,value in w1.items(): | ||