<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl">
	<id>http://brain.fuw.edu.pl/edu/index.php?action=history&amp;feed=atom&amp;title=TI%2FPodstawy_XML_i_jego_parsowanie</id>
	<title>TI/Podstawy XML i jego parsowanie - Historia wersji</title>
	<link rel="self" type="application/atom+xml" href="http://brain.fuw.edu.pl/edu/index.php?action=history&amp;feed=atom&amp;title=TI%2FPodstawy_XML_i_jego_parsowanie"/>
	<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=TI/Podstawy_XML_i_jego_parsowanie&amp;action=history"/>
	<updated>2026-04-23T10:00:09Z</updated>
	<subtitle>Historia wersji tej strony wiki</subtitle>
	<generator>MediaWiki 1.34.1</generator>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=TI/Podstawy_XML_i_jego_parsowanie&amp;diff=1937&amp;oldid=prev</id>
		<title>Jarekz: Utworzono nową stronę &quot; &lt;!-- * idea xml (język deklaratywny itp.) * parsowanie xml za pomocą etree (lxml) * idea pisania parsera (rekurencja i chodzenie po drzewach) * co zrobić z plikami x...&quot;</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=TI/Podstawy_XML_i_jego_parsowanie&amp;diff=1937&amp;oldid=prev"/>
		<updated>2015-05-23T13:50:26Z</updated>

		<summary type="html">&lt;p&gt;Utworzono nową stronę &amp;quot; &amp;lt;!-- * idea xml (język deklaratywny itp.) * parsowanie xml za pomocą etree (lxml) * idea pisania parsera (rekurencja i chodzenie po drzewach) * co zrobić z plikami x...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nowa strona&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
* idea xml (język deklaratywny itp.)&lt;br /&gt;
* parsowanie xml za pomocą etree (lxml)&lt;br /&gt;
* idea pisania parsera (rekurencja i chodzenie po drzewach)&lt;br /&gt;
* co zrobić z plikami xml, które mają nazwę namespace'a w tagach&lt;br /&gt;
* DTD, XMLSchema - trzeba powiedzieć coś o walidacji dokumentów XML (ale nie za dużo bo to temat na osobny wykład).  --&amp;gt;&lt;br /&gt;
==XML==&lt;br /&gt;
Nazwa XML jest skrótem od {{ang|Extensible Markup Language}}, co w wolnym tłumaczeniu oznacza &amp;quot;rozszerzalny język znaczników&amp;quot;. Sam XML jest uniwersalnym językiem przeznaczonym do reprezentowania różnych danych w strukturalizowany sposób.&lt;br /&gt;
&lt;br /&gt;
{{solution|title=Język formalny|text= język złożony ze wszystkich słów (wyrażeń) uzyskiwanych za pomocą ściśle określonych reguł; definiowany zwykle przez gramatykę formalną (zgodnie ze składnią języka formalnego); podstawowe pojęcie lingwistyki matematycznej (za [http://encyklopedia.pwn.pl/haslo.php?id=3917941 Encyklopedią PWN]&lt;br /&gt;
).}}&lt;br /&gt;
XML nie jest językiem programowania i nie trzeba być programistą, by z niego korzystać. XML sprawia, że generowanie danych i ich odczyt są znacznie łatwiejsze, zapewniając strukturę łatwą do generacji i odczytu programowego. XML jest rozszerzalny i niezależny od platformy, i wykorzystuje Unicode do reprezentacji tekstu.&lt;br /&gt;
&lt;br /&gt;
XML korzysta z tagów (słowa ujęte w '&amp;lt;' i '&amp;gt;') oraz atrybutów (w postaci nazwa=&amp;quot;wartość&amp;quot;), bardzo podobnie do HTMLa. Jednakowoż HTML definiuje dokładne znaczenia każdego z tagów i jego atrybutów, jak również ich wygląd w przeglądarce, XML używa tagów tylko do rozgraniczenia pewnej części z całego dokumentu, a interpretację znaczenia pozostawia aplikacji odczytujacej te dane. I tak &amp;quot;&amp;amp;lt;p&amp;amp;gt;&amp;quot; w dokumencie XML-owym  nie oznacza początku paragrafu. W zależności od kontekstu, czy konstrukcji formatu danych taki tag może oznaczać dowolny parametr zaczynający się na &amp;quot;p&amp;quot; albo na inną literę alfabetu.&lt;br /&gt;
&lt;br /&gt;
Pliki XML-owe tak samo jako HTML-owe są plikami tekstowymi. Dzięki temu można przeglądać dane bez potrzeby korzystania z dodatkowych aplikacji, a w ostateczności edytować je korzystając z edytora tekstu. Postać tekstowa umożliwia też łatwiejsze przeglądanie tekstu w celu usuwania błędów. &lt;br /&gt;
&lt;br /&gt;
W przeciwieństwie do HTML, reguły dotyczące plików XML są ścisłe i nie naruszalne. Źle napisany tag, zgubiony nawias czy atrybut nie ujęty w cudzysłów czyni plik XML bezużytecznym, podczas gdy w HTML taka praktyka jest dozwolona. Oficjalna specyfikacja języka XML zabrania aplikacjom domyślać się co ma znaczyć dany fragment uszkodzonego plik XML; jeśli w pliku jest błąd program powinien wstrzymać wykonywanie i zgłosić błąd.&lt;br /&gt;
&lt;br /&gt;
Ze względu na postać tekstową danych i rozgraniczanie ich za pomocą tekstowych znaczników, pliki XML-owe są znacząco większe niż pliki biarne z takimi samymi danymi.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;XML pozwala na zdefiniowanie nowego formatu poprzez łączenie lub korzystanie z innego. Ponieważ różne formaty są tworzone zupełnie niezalenie, mogą mieć tagi lub atrybuty o takiej samej nazwie, co powoduje dwuznaczność przy łączeniu takich dokumentów (np. w jednym &amp;quot;&amp;amp;lt;p&amp;amp;gt;&amp;quot; oznacza &amp;quot;paragraf&amp;quot;, a w innym &amp;quot;pisarza&amp;quot;). W celu wyeliminowania takiej dwuznaczności w XML wprowadzona mechanizm przestrzeni nazw.(...)XML Schema został zaprojektowany, by odzwierciedlać to wsparcie dla modularności na poziomie definiowania struktury dokumentu XML, ułatwiając połaczeniu dwóch schematów w celu stworzenia trzeciego, który obejmuje strukturę połaczonych dokumentów.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
([http://www.w3.org/XML/1999/XML-in-10-points.pl.html XML in 10 points], [http://www.w3.org/People/domain?domain=Communications W3C Communications Team] tłumaczenie Jacek Gleń)&lt;br /&gt;
&lt;br /&gt;
=== Chwila refleksji ===&lt;br /&gt;
&lt;br /&gt;
Zatrzymajmy się na chwilę, żeby się z oswoić z wyglądem pliku xml [http://escher.fuw.edu.pl/~mm/swps/swps_lb_1.xml prosciutkiego ] i [http://escher.fuw.edu.pl/~mm/swps/swps_lb_1.tag bardziej skomplikowanego]. Podziwiajmy przez chwilę drzewiastą strukturę tych plików, popatrzmy jakie są zasadnicze różnice między nimi.&lt;br /&gt;
&lt;br /&gt;
==Parsery==&lt;br /&gt;
&lt;br /&gt;
===lxml.etree===&lt;br /&gt;
Moduł lxml jest pythonową nakładką na na biblioteki [http://xmlsoft.org/ '''libxml2'''] i [http://xmlsoft.org/XSLT/ '''libxslt'''] napisane w języku &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt;. Jest o tyle przyjemna, że łączy szybkość działania i kompletność z naturalnym dla nas interfejsem pythonowym i jest kompatybilna z [http://effbot.org/zone/element-index.htm '''ElementTree'''].&lt;br /&gt;
&lt;br /&gt;
Poniższe przykłady są częściowo zaczerpnięte z [http://lxml.de/tutorial.html samouczka do '''lxml.etree'''] autorstwa '''Stefana Behnela'''.&lt;br /&gt;
&lt;br /&gt;
====import====&lt;br /&gt;
Zazwyczaj piszemy:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;from lxml import etree&amp;lt;/source&amp;gt;&lt;br /&gt;
W przypadku, gdy program nie będzie korzystał z funkcjonalności dostępnej wyłącznie w '''lxml.etree''' import można zrobić w następujący sposób:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
  from lxml import etree&lt;br /&gt;
  print &amp;quot;running with lxml.etree&amp;quot;&lt;br /&gt;
except ImportError:&lt;br /&gt;
  try:&lt;br /&gt;
    # Python 2.5&lt;br /&gt;
    import xml.etree.cElementTree as etree&lt;br /&gt;
    print &amp;quot;running with cElementTree on Python 2.5+&amp;quot;&lt;br /&gt;
  except ImportError:&lt;br /&gt;
    try:&lt;br /&gt;
      # Python 2.5&lt;br /&gt;
      import xml.etree.ElementTree as etree&lt;br /&gt;
      print &amp;quot;running with ElementTree on Python 2.5+&amp;quot;&lt;br /&gt;
    except ImportError:&lt;br /&gt;
      try:&lt;br /&gt;
        # normal cElementTree install&lt;br /&gt;
        import cElementTree as etree&lt;br /&gt;
        print &amp;quot;running with cElementTree&amp;quot;&lt;br /&gt;
      except ImportError:&lt;br /&gt;
        try:&lt;br /&gt;
          # normal ElementTree install&lt;br /&gt;
          import elementtree.ElementTree as etree&lt;br /&gt;
          print &amp;quot;running with ElementTree&amp;quot;&lt;br /&gt;
        except ImportError:&lt;br /&gt;
          print &amp;quot;failed to import ElementTree from any known place&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Klasa &amp;lt;tt&amp;gt;Element&amp;lt;/tt&amp;gt;====&lt;br /&gt;
&amp;lt;tt&amp;gt;Element&amp;lt;/tt&amp;gt; jest podstawowym kontenerem w &amp;lt;tt&amp;gt;ElementTree&amp;lt;/tt&amp;gt;. W większości wypadków do drzewa XML-owego dostajemy się przez tęże klasę. &lt;br /&gt;
&lt;br /&gt;
Tworzymy obiekt o nazwie &amp;lt;tt&amp;gt;root&amp;lt;/tt&amp;gt; klasy &amp;lt;tt&amp;gt;Element&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pycon&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; root = etree.Element(&amp;quot;root&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do XML-owej nazwy znacznika (taga) dostajemy się za pomocą pola &amp;lt;tt&amp;gt;tag&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pycon&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print root.tag&lt;br /&gt;
root&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obiekty klasy &amp;lt;tt&amp;gt;Element&amp;lt;/tt&amp;gt; tworzą strukturę drzewa XML-owego. Żeby skontruować dzieci i dodać je do rodzica, można m.in. użyć metody &amp;lt;tt&amp;gt;append&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pycon&amp;quot;&amp;gt; &amp;gt;&amp;gt;&amp;gt; root.append( etree.Element(&amp;quot;child1&amp;quot;) )&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Można też do tego użyć fabryki &amp;lt;tt&amp;gt;SubElement&amp;lt;/tt&amp;gt;, która wymaga podania nazwy rodzica jako parametru oraz takich samych parametrów, jak fabryka &amp;lt;tt&amp;gt;Element&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pycon&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; child2 = etree.SubElement(root, &amp;quot;child2&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; child3 = etree.SubElement(root, &amp;quot;child3&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zobaczmy, jakie drzewo xml-owe stworzyliśmy:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pycon&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print(etree.tostring(root, pretty_print=True))&lt;br /&gt;
&amp;lt;root&amp;gt;&lt;br /&gt;
  &amp;lt;child1/&amp;gt;&lt;br /&gt;
  &amp;lt;child2/&amp;gt;&lt;br /&gt;
  &amp;lt;child3/&amp;gt;&lt;br /&gt;
&amp;lt;/root&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;lt;tt&amp;gt;Element&amp;lt;/tt&amp;gt;y są sekwencjami====&lt;br /&gt;
Żeby było jeszcze prościej, elementy zachowują się jak sekwencje:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pycon&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; child = root[0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print child.tag&lt;br /&gt;
child1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print len(root)&lt;br /&gt;
3&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; root.index(root[1]) # tylko w lxml.etree!&lt;br /&gt;
1&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; children = list(root)&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for child in root:&lt;br /&gt;
...     print child.tag&lt;br /&gt;
child1&lt;br /&gt;
child2&lt;br /&gt;
child3&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; root.insert(0, etree.Element(&amp;quot;child0&amp;quot;))&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; start = root[:1]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; end   = root[-1:]&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print start[0].tag&lt;br /&gt;
child0&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print end[0].tag&lt;br /&gt;
child3&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; root[0] = root[-1] # zmienia kolejność elementów w drzewie w lxml.etree&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for child in root:&lt;br /&gt;
...     print child.tag&lt;br /&gt;
child3&lt;br /&gt;
child1&lt;br /&gt;
child2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====&amp;lt;tt&amp;gt;Element&amp;lt;/tt&amp;gt;y mają atrybuty====&lt;br /&gt;
W XML-u tagi mogą mieć atrybuty. Tagi z atrybutami, można tworzyć bezpośednio za pomocą klasy &amp;lt;tt&amp;gt;Element&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pycon&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; root = etree.Element(&amp;quot;przedmiot&amp;quot;, interesujacy=&amp;quot;strasznie&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; etree.tostring(root)&lt;br /&gt;
b'&amp;lt;przedmiot interesujacy=&amp;quot;strasznie&amp;quot;/&amp;gt;'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Dostęp do atrybutów zapewniany jest przez metody &amp;lt;tt&amp;gt;set&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;get&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pycon&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print root.get(&amp;quot;interesting&amp;quot;)&lt;br /&gt;
None&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print root.get(&amp;quot;interesujacy&amp;quot;)&lt;br /&gt;
strasznie&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; root.set(&amp;quot;interesujacy&amp;quot;,&amp;quot;troszke&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print root.get(&amp;quot;interesujacy&amp;quot;)&lt;br /&gt;
troszke&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Za pomocą metody &amp;lt;tt&amp;gt;set&amp;lt;/tt&amp;gt; można tez atrybuty dodawać:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pycon&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; root.set(&amp;quot;trudny&amp;quot;,&amp;quot;troszke&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print root.get(&amp;quot;interesujacy&amp;quot;)&lt;br /&gt;
troszke&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Atrybuty można też uzyskać za pomocą metody &amp;lt;tt&amp;gt;attrib&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pycon&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print root.attrib&lt;br /&gt;
{'interesujacy': 'troszke', 'trudny': 'troszke'}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Atrybuty są słownikami === &lt;br /&gt;
&lt;br /&gt;
Kontynuując poprzedni przykład, &amp;lt;tt&amp;gt;attrib&amp;lt;/tt&amp;gt; zwraca nam słownik atrybutów danego taga:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pycon&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; child = root[0]&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; child.tag&lt;br /&gt;
'child1'&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; child.set(&amp;quot;atr&amp;quot;, &amp;quot;1&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print child&lt;br /&gt;
&amp;lt;Element child1 at 13943a0&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; child.attrib&lt;br /&gt;
{'atr': '1'}&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; child.set(&amp;quot;atr2&amp;quot;, &amp;quot;2&amp;quot;)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; child.attrib&lt;br /&gt;
{'atr2': '2', 'atr': '1'}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pliki ===&lt;br /&gt;
Parsery xml jednak najczęściej służą do przetwarzania w jakiś sposób plików, a nie tylko tworzenia struktury xml'owej w pamięci, więc teraz przyjrzymy się prostym przykładom plików:&lt;br /&gt;
==== Odczyt ====&lt;br /&gt;
 &amp;lt;root&amp;gt;&lt;br /&gt;
 &amp;lt;child&amp;gt;One&amp;lt;/child&amp;gt;&lt;br /&gt;
 &amp;lt;child&amp;gt;Two&amp;lt;/child&amp;gt;&lt;br /&gt;
 &amp;lt;/root&amp;gt;&lt;br /&gt;
Skopiujmy gdzieś ten kawałek, i zapiszmy pod nazwą example.xml.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; xml_file = &amp;quot;/sciezka/bezwzgledna/example.xml&amp;quot;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; tree = ET.parse(xml_file)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; element = tree.getroot()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print element.tag&lt;br /&gt;
root&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for subelement in element:&lt;br /&gt;
	print subelement.text&lt;br /&gt;
	&lt;br /&gt;
One&lt;br /&gt;
Two&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Żeby nie mieszało nam się, które słówka są kluczowe, a które możemy samodzielnie wymyślać, przepiszmy ten przykład na język polski:&lt;br /&gt;
 &amp;lt;korzen&amp;gt;&lt;br /&gt;
 &amp;lt;dziecko&amp;gt;Pierwsze&amp;lt;/dziecko&amp;gt;&lt;br /&gt;
 &amp;lt;dziecko&amp;gt;Drugie&amp;lt;/dziecko&amp;gt;&lt;br /&gt;
 &amp;lt;/korzen&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; plik_xml = &amp;quot;/Users/magda/przyklad.xml&amp;quot;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; drzewko = ET.parse(plik_xml)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; el = drzewko.getroot()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; for podelement in el:&lt;br /&gt;
	print podelement.text&lt;br /&gt;
	&lt;br /&gt;
Pierwsze&lt;br /&gt;
Drugie&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print el.tag&lt;br /&gt;
korzen&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Wzbogaćmy nasz przykładowy plik o atrybuty w tagach:&lt;br /&gt;
 &amp;lt;korzen&amp;gt;&lt;br /&gt;
 &amp;lt;dziecko atrybut=&amp;quot;wartosc&amp;quot; atrybut2=&amp;quot;wartosc2&amp;quot;&amp;gt;Pierwsze&amp;lt;/dziecko&amp;gt;&lt;br /&gt;
 &amp;lt;dziecko&amp;gt;Drugie&amp;lt;/dziecko&amp;gt;&lt;br /&gt;
 &amp;lt;/korzen&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from xml.etree import ElementTree as ET&lt;br /&gt;
&lt;br /&gt;
plik_xml = &amp;quot;/Users/magda/przyklad.xml&amp;quot;&lt;br /&gt;
drzewko = ET.parse(plik_xml)&lt;br /&gt;
el = drzewko.getroot()&lt;br /&gt;
for podelement in el:&lt;br /&gt;
        print podelement.text&lt;br /&gt;
        print podelement.attrib&lt;br /&gt;
&lt;br /&gt;
# Wynik wykonania:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
Pierwsze&lt;br /&gt;
{'atrybut2': 'wartosc2', 'atrybut': 'wartosc'}&lt;br /&gt;
Drugie&lt;br /&gt;
{}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==== Zapis ====&lt;br /&gt;
&lt;br /&gt;
=== Przydatne funkcje ===&lt;br /&gt;
API biblioteki lxml.etree oraz xml.etree są bardzo podobne. Na potrzeby naszych zajęć prawdopodobnie nawet nie zauważymy różnicy. Wygodna dokumentacja jest [http://docs.python.org/library/xml.etree.elementtree.html tu(xml.etree)] oraz [http://lxml.de/api/index.html tu (lxml)]&lt;br /&gt;
Poniżej kilka przykładów.&lt;br /&gt;
==== find / findall ==== &lt;br /&gt;
pozwalające wybrać pierwszy/wszystkie tagi o zadanej nazwie:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;korzen&amp;gt;&lt;br /&gt;
 &amp;lt;dziecko atrybut=&amp;quot;wartosc&amp;quot; atrybut2=&amp;quot;wartosc2&amp;quot;&amp;gt;Pierwsze&amp;lt;/dziecko&amp;gt;&lt;br /&gt;
 &amp;lt;dziecko&amp;gt;Drugie&amp;lt;/dziecko&amp;gt;&lt;br /&gt;
 &amp;lt;atrapa&amp;gt;Atrapa&amp;lt;/atrapa&amp;gt;&lt;br /&gt;
 &amp;lt;atrapa&amp;gt;Atrapa2&amp;lt;/atrapa&amp;gt;&lt;br /&gt;
 &amp;lt;atrapa&amp;gt;Atrapa3&amp;lt;/atrapa&amp;gt;&lt;br /&gt;
 &amp;lt;/korzen&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from xml.etree import ElementTree as ET&lt;br /&gt;
&lt;br /&gt;
plik_xml = &amp;quot;/Users/magda/przyklad.xml&amp;quot;&lt;br /&gt;
drzewko = ET.parse(plik_xml)&lt;br /&gt;
el = drzewko.getroot()&lt;br /&gt;
dzieci = el.findall(&amp;quot;dziecko&amp;quot;)&lt;br /&gt;
for d in dzieci:&lt;br /&gt;
        print d.text&lt;br /&gt;
atrapy = el.findall(&amp;quot;atrapa&amp;quot;)&lt;br /&gt;
for a in atrapy:&lt;br /&gt;
        print a.text&lt;br /&gt;
&lt;br /&gt;
# Wynik wykonania:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
Pierwsze&lt;br /&gt;
Drugie&lt;br /&gt;
Atrapa&lt;br /&gt;
Atrapa2&lt;br /&gt;
Atrapa3&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A ile tagów o nazwie dziecko zostanie znalezione w tym przypadku?:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;korzen&amp;gt;&lt;br /&gt;
 &amp;lt;dziecko atrybut=&amp;quot;wartosc&amp;quot; atrybut2=&amp;quot;wartosc2&amp;quot;&amp;gt;Pierwsze&amp;lt;/dziecko&amp;gt;&lt;br /&gt;
 &amp;lt;dziecko&amp;gt;Drugie&amp;lt;/dziecko&amp;gt;&lt;br /&gt;
 &amp;lt;atrapa&amp;gt;Atrapa&amp;lt;/atrapa&amp;gt;&lt;br /&gt;
 &amp;lt;atrapa&amp;gt;Atrapa2&amp;lt;/atrapa&amp;gt;&lt;br /&gt;
 &amp;lt;atrapa&amp;gt;Atrapa3&amp;lt;/atrapa&amp;gt;&lt;br /&gt;
 &amp;lt;dziecko&amp;gt;&lt;br /&gt;
         &amp;lt;dziecko&amp;gt;&lt;br /&gt;
                 &amp;lt;dziecko&amp;gt;&lt;br /&gt;
                 &amp;lt;/dziecko&amp;gt;&lt;br /&gt;
         &amp;lt;/dziecko&amp;gt;&lt;br /&gt;
 &amp;lt;/dziecko&amp;gt;&lt;br /&gt;
 &amp;lt;/korzen&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from xml.etree import ElementTree as ET&lt;br /&gt;
&lt;br /&gt;
plik_xml = &amp;quot;/Users/magda/przyklad.xml&amp;quot;&lt;br /&gt;
drzewko = ET.parse(plik_xml)&lt;br /&gt;
el = drzewko.getroot()&lt;br /&gt;
dzieci = el.findall(&amp;quot;dziecko&amp;quot;)&lt;br /&gt;
print len(dzieci)&lt;br /&gt;
&lt;br /&gt;
# Wynika wykonania:&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
3&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tworzenie własnego parsera ===&lt;br /&gt;
&lt;br /&gt;
Do budowania drzewa, na którym potem wykonujemy wszystkie operacje, jest używany standardowy &amp;quot;parser&amp;quot;. Ale czasem chcielibyśmy wykonać jakieś operacje już na etapie budowania drzewa. Mamy taką możliwość, możemy utworzyć własną klasę, której przedefiniujemy odpowiednie metody, i podać ją jako parametr odpowiednim funkcjom.&lt;br /&gt;
W szczególności w powyższych przykładach dotyczących plików mogliśmy funkcji parse jako drugi parametr podać nasz własny parser:&lt;br /&gt;
&lt;br /&gt;
 xml.etree.ElementTree.parse(source, parser=None)&lt;br /&gt;
     Parses an XML section into an element tree. source is a filename or file object    containing XML data. parser is an optional parser instance. If not given, the standard XMLParser parser is used. Returns an ElementTree instance.&lt;br /&gt;
&lt;br /&gt;
A oto przykład tworzenia własnego parsera, który przy okazji parsowania zlicza głębokość drzewka:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pycon&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; from xml.etree.ElementTree import XMLParser&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; class MaxDepth:                     # The target object of the parser&lt;br /&gt;
...     maxDepth = 0&lt;br /&gt;
...     depth = 0&lt;br /&gt;
...     def start(self, tag, attrib):   # Called for each opening tag.&lt;br /&gt;
...         self.depth += 1&lt;br /&gt;
...         if self.depth &amp;gt; self.maxDepth:&lt;br /&gt;
...             self.maxDepth = self.depth&lt;br /&gt;
...     def end(self, tag):             # Called for each closing tag.&lt;br /&gt;
...         self.depth -= 1&lt;br /&gt;
...     def data(self, data):&lt;br /&gt;
...         pass            # We do not need to do anything with data.&lt;br /&gt;
...     def close(self):    # Called when all data has been parsed.&lt;br /&gt;
...         return self.maxDepth&lt;br /&gt;
...&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; target = MaxDepth()&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; parser = XMLParser(target=target)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; exampleXml = &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
... &amp;lt;a&amp;gt;&lt;br /&gt;
...   &amp;lt;b&amp;gt;&lt;br /&gt;
...   &amp;lt;/b&amp;gt;&lt;br /&gt;
...   &amp;lt;b&amp;gt;&lt;br /&gt;
...     &amp;lt;c&amp;gt;&lt;br /&gt;
...       &amp;lt;d&amp;gt;&lt;br /&gt;
...       &amp;lt;/d&amp;gt;&lt;br /&gt;
...     &amp;lt;/c&amp;gt;&lt;br /&gt;
...   &amp;lt;/b&amp;gt;&lt;br /&gt;
... &amp;lt;/a&amp;gt;&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; parser.feed(exampleXml)&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; parser.close()&lt;br /&gt;
4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pamiętaj, że gdy używamy argumentu target, XMLParser() nie zwraca automatycznie drzewa -- jesli chcemy, musimy sami je zbudować w naszej klasie, którą podajemy jako target.&lt;br /&gt;
&lt;br /&gt;
==== Ćwiczenie ====&lt;br /&gt;
Napisz parser, który podczas budowania drzewa zlicza ilość elementów o nazwie child  Przetestuj jego działanie.&lt;br /&gt;
&lt;br /&gt;
=== Zadania ===&lt;br /&gt;
:&amp;lt;b&amp;gt;Termin oddania projektów do 15-tego czerwca!&amp;lt;/b&amp;gt;&lt;br /&gt;
:&amp;lt;b&amp;gt;Zmiany w terści zadań, wynikające z uwag studentów, akceptowane są do 1-go czerwca!&amp;lt;/b&amp;gt;&lt;br /&gt;
==== Wstęp do projektu zaliczeniowego: Temat 1 &amp;amp;mdash; tworzenie klas na podstawie opisu w XML ====&lt;br /&gt;
=====Dynamiczna generacja klas=====&lt;br /&gt;
Python umożliwia dynamiczną generację klas.&lt;br /&gt;
&lt;br /&gt;
Można to robić na dwa sposoby. W funkcji:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def klasa_p(p):&lt;br /&gt;
  class P(object):&lt;br /&gt;
     x = p&lt;br /&gt;
  return P&lt;br /&gt;
P_11 = klasa_p(11)&lt;br /&gt;
p_11 = P_11()&lt;br /&gt;
assert p_11.x == 11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przy normalnej definicji klasy, wykonuje się sekwencja poleceń. Na końcu bloku &amp;lt;tt&amp;gt;class&amp;lt;/tt&amp;gt; otrzymujemy pewien zestaw zmiennych w przestrzeni nazw (namespace), który jest słownikiem. Można też od razu stworzyć swój namespace, w tym ypadku pewien słownik i za pomocą funkcji &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt; klasę o odpowieniej nazwie.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
B = type('B', (object,), dict(x=11))&lt;br /&gt;
assert B().x == 11&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Argumentami funkcji type są &amp;amp;mdash; nazwa klasy, lista rodziców i treść klasy, czyli słownik. czyli de facto jej namespace.&lt;br /&gt;
Wiedząc, że w pythonie można dynamicznie tworzyć klasy tak jak w poniższym przykładzie:&lt;br /&gt;
&lt;br /&gt;
I kolejne przykłady:&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;source lang=&amp;quot;Python&amp;quot;&amp;gt;&lt;br /&gt;
class C(object):&lt;br /&gt;
  def f(self, x): return x&lt;br /&gt;
  f = lambda x: None&lt;br /&gt;
assert C().f(33) == None&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
par = &amp;quot;self.y * self.y&amp;quot;&lt;br /&gt;
x = &amp;quot;y&amp;quot;&lt;br /&gt;
d={}&lt;br /&gt;
d[x] = 10&lt;br /&gt;
d[&amp;quot;action&amp;quot;] = lambda self: eval(par)&lt;br /&gt;
Bar = type('Bar',(object,),d)&lt;br /&gt;
b = Bar()&lt;br /&gt;
print b.y&lt;br /&gt;
print b.action()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
=====Treść projektu=====&lt;br /&gt;
Napisz prosty program, który z zadanego opisu XML tworzy klasę. Opis XML może wyglądać np. tak:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;class nazwa=&amp;quot;Test&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;attribute nazwa=&amp;quot;y&amp;quot; wartosc=&amp;quot;10&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;/attribute&amp;gt;&lt;br /&gt;
 &amp;lt;attribute nazwa=&amp;quot;x&amp;quot; wartosc=&amp;quot;5&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;/attribute&amp;gt;&lt;br /&gt;
 &amp;lt;method nazwa=&amp;quot;action&amp;quot; tresc=&amp;quot;self.y * self.y&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;/method&amp;gt;&lt;br /&gt;
 &amp;lt;method nazwa=&amp;quot;metoda2&amp;quot; tresc=&amp;quot;self.x * self.y&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;/method&amp;gt;&lt;br /&gt;
 &amp;lt;/class&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W znaczniku class w atrybucie nazwa jest zapisana nazwa klasy. W znacznikach o nazwie &amp;quot;attribute&amp;quot; w atrybucie &amp;quot;nazwa&amp;quot; jest zapisana nazwa atrybutu klasy, w atrybucie &amp;quot;wartosc&amp;quot; -- jego wartosc.&lt;br /&gt;
W znacznikach &amp;quot;method&amp;quot; w atrybucie &amp;quot;nazwa&amp;quot; jest nazwa metody, a atrybucie &amp;quot;tresc&amp;quot; -- jej tresc. Dopuszczamy wyłącznie bardzo proste metody, bezparametrowe, operujące na atrybutach obiektu i wyłącznie zwracające wynik tych operacji.&lt;br /&gt;
Nieprecyzyjności w sformułowaniu należy zinterpretować na własną korzyść, tzn tak, jak nam ławiej zaimplementować rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
==== Projekt zaliczeniowy: Temat 1 -- tworzenie klas na podstawie opisu w XML ====&lt;br /&gt;
&lt;br /&gt;
Rozwiń powyższe zadanie.&lt;br /&gt;
* Zaprojektuj sposób opisu klasy, uwzględniający możliwie dużo aspektów nie objętych obecną wersją, np.:&lt;br /&gt;
** metody z argumentami&lt;br /&gt;
** zmianę metody init&lt;br /&gt;
** metody, które coś wypisują&lt;br /&gt;
** oddzielnie metody klasowe od metod obiektu&lt;br /&gt;
** oddzielnie atrybuty klasowe od atrybutów obiektu&lt;br /&gt;
** dziedziczenie&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Sposób opisu zaprojektowany przez Ciebie może być zupełnie inny niż zaproponowany we wstępie do zadania.&lt;br /&gt;
Napisz parser, który na podstawie opisu XML zgodnego z Twoimi &amp;quot;zasadami&amp;quot; zaimplementuje opisane klasy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== FAQ do Tematu 1 ====&lt;br /&gt;
&lt;br /&gt;
==== Wstęp do projektu zaliczeniowego: Temat 2 ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Projekt zaliczeniowy: Temat 2 -- Parsowanie pliku z metaopisem danych ====&lt;br /&gt;
&lt;br /&gt;
Rozwiń swoją klasę do cięcia danych z pracowni o automatyczne wczytywanie wszystkich możliwych parametrów, typu częstość próbkowania, nazwy/ilość elektrod z zadanego pliku .xml&lt;br /&gt;
Format pliku .xml -- tak jak pliki .info z pracowni.&lt;br /&gt;
Przy ocenie zadania będzie brana pod uwagę dokładność implementacji: odporność na błędy, łapanie wyjątków, jakość dokumentacji, itd&lt;br /&gt;
&lt;br /&gt;
==== FAQ do Tematu 2 ====&lt;br /&gt;
&lt;br /&gt;
==Literatura==&lt;br /&gt;
Korzystałyśmy z:&lt;br /&gt;
# [http://www.w3.org/XML/1999/XML-in-10-points.pl.html XML in 10 points]&lt;br /&gt;
# [http://lxml.de/tutorial.html samouczek do lxml.etree]&lt;/div&gt;</summary>
		<author><name>Jarekz</name></author>
		
	</entry>
</feed>