Zanurkuj w Pythonie/Skrypty i strumienie - wszystko razem: Różnice pomiędzy wersjami
Usunięta treść Dodana treść
drobne techniczne |
Nie podano opisu zmian |
||
Linia 4:
Zaczniemy od skryptu, który pobiera argumenty z linii poleceń używając modułu <code>getopt</code>.
<
# ...
try:
Linia 12:
for opt, arg in opts:
# ...
</syntaxhighlight>
Tworzymy nową instancję klasy <code>KantGenerator</code> i przekazujemy jej plik z gramatyką oraz źródło, które może być, ale nie musi, podane w linii poleceń.
<
Instancja klasy <code>KantGenerator</code> automatycznie wczytuje gramatykę, która jest plikiem XML. Wykorzystujemy naszą funkcję <code>openAnything</code> do otwarcia pliku (który może być ulokowany lokalnie lub na zdalnym serwerze), następnie używamy wbudowanego zestawu funkcji parsujących <code>minidom</code> do sparsowania XML-a do postaci drzewa obiektów Pythona.
<
sock = toolbox.openAnything(source)
xmldoc = minidom.parse(sock).documentElement
sock.close()</
Ach i po drodze wykorzystujemy naszą wiedzę o strukturze dokumentu XML do utworzenia małego bufora referencji, którymi są po prostu elementy dokumentu XML.
<
for ref in self.grammar.getElementsByTagName("ref"):
self.refs[ref.attributes["id"].value] = ref</
Jeśli został podany jakiś materiał źródłowy w linii poleceń, używamy go. W przeciwnym razie na podstawie gramatyki wyszukujemy referencję na najwyższym poziomie (tą do której nie mają odnośników żadne inne elementy) i używamy jej jako punktu startowego.
<
xrefs = {}
for xref in self.grammar.getElementsByTagName("xref"):
Linia 39:
xrefs = xrefs.keys()
standaloneXrefs = [e for e in self.refs.keys() if e not in xrefs]
return '<xref id="%s"/>' % random.choice(standaloneXrefs)</
Teraz przedzieramy się przez materiał źródłowy. Ten materiał to także XML i parsujemy go węzeł po węźle. Aby podzielić nieco kod i uczynić go łatwiejszym w utrzymaniu, używamy oddzielnych funkcji obsługi (ang. ''handlers'') dla każdego typu węzła.
<
handlerMethod = getattr(self, "do_%s" % node.tagName)
handlerMethod(node)</
Przelatujemy przez gramatykę, parsując wszystkie elementy potomne każdego elementu <tt>p</tt>,
<
# ...
if doit:
for child in node.childNodes: self.parse(child)</
zastępując elementy <code>choice</code> losowym elementem potomnym,
<
self.parse(self.randomChildElement(node))</
i zastępując elementy <tt>xref</tt> losowym elementem potomnym odpowiedniego elementu <tt>ref</tt>, który wcześniej został zachowany w buforze.
<
id = node.attributes["id"].value
self.parse(self.randomChildElement(self.refs[id]))</
W końcu parsujemy wszystko do zwykłego tekstu,
<
text = node.data
# ...
self.pieces.append(text)</
który wypisujemy.
<
# ...
k = KantGenerator(grammar, source)
print k.output()</
<noinclude>
|