Import sys
from xml.sax.saxutils import XMLGenerator
g = XMLGenerator(sys.stdout)
g.startDocument()
g.startElement("expression", {})
g.startElement("operation", {"type": "+"})
g.startElement("operand", {})
g.characters("2")
g.endElement("operand")
g.startElement("operand", {})
g.startElement("operation", {"type": "*"})
g.startElement("operand", {})
g.characters("3")
g.endElement("operand")
g.startElement("operand", {})
g.characters("4")
g.endElement("operand")
g.endElement("operation")
g.endElement("operand")
g.endElement("operation")
g.endElement("expression")
g.endDocument(
Ағаш құрудың обьектілі моделі құжатының мысалы былай көрінуі мүмкін:
from xml.dom import minidom
dom = minidom.Document()
e1 = dom.createElement("expression")
dom.appendChild(e1)
p1 = dom.createElement("operation")
p1.setAttribute('type', '+')
x1 = dom.createElement("operand")
x1.appendChild(dom.createTextNode("2"))
p1.appendChild(x1)
e1.appendChild(p1)
p2 = dom.createElement("operation")
p2.setAttribute('type', '*')
x2 = dom.createElement("operand")
x2.appendChild(dom.createTextNode("3"))
p2.appendChild(x2)
x3 = dom.createElement("operand")
x3.appendChild(dom.createTextNode("4"))
p2.appendChild(x3)
x4 = dom.createElement("operand")
x4.appendChild(p2)
p1.appendChild(x4)
print dom.toprettyxml()
Тегтер генерациясында және басқа бөліктерінде SAX командасын қолдану кезекті түрде берілетінін аңғару оңай, ал бірдей DOM-дарды ағындарды қалыптастыру командарының түрлі кезектестігі және оның басқа ағындармен байланысы арқылы құруға болады.
Әрине, көрсетілген мысалдар теориялық сипатқа ие, өйткені іс жүзінде XML-құжаттарын осылайша құру әдетте келмейді.
XML-құжатты талдау
Дайын XML-құжатымен жұмыс істеу үшін XML-анализаторын қолдану қажет. Document класс обьектісінің құрылуымен XML-құжаты parse ( ) функциясы көмегімен тек бір жолда кездеседі. Ескере кететіні, стандартты xml пакетінен басқа PyXML пакетін немесе баламалы коммерциялық пакетті қоюға болады. Дегенмен құрастырушылар DOM Level 2 стандартымен шыққан, бірегей API ұстануға тырысады.
import xml.dom.minidom
dom = xml.dom.minidom.parse("expression.xml")
dom.normalize()
def output_tree(node, level=0):
if node.nodeType == node.TEXT_NODE:
if node.nodeValue.strip():
print ". "*level, node.nodeValue.strip()
else: # ELEMENT_NODE или DOCUMENT_NODE
atts = node.attributes or {}
att_string = ", ".join(
["%s=%s " % (k, v) for k, v in atts.items()])
print ". "*level, node.nodeName, att_string
for child in node.childNodes:
output_tree(child, level+1)
output_tree(dom)
Бұл мысалда ағаш, ағын кірісінде қабылдайтын және барлық енген ағындар үшін рекурсивті шақырылатын, нақты output_tree() функциясы көмегімен шығарылады.
Нәтижесі шамамен келесідей шығады:
#document
. expression
. . operation type=+
. . . operand
. . . . 2
. . . operand
. . . . operation type=*
. . . . . operand
. . . . . . 3
. . . . . operand
. . . . . . 4
Барлық мәтіндік фрагменттер біріктірілуі үшін, мұнда normalize() әдісі қолданылады (әйтпесе қатарынан мәтінмен берілген бірнеше түйіндерді әкелуі мүмкін).
Тіпті шағын мысалдарда ағындар атрибуттарын қолданғанын байқауға болады: node.nodeType ағын түрін көрсетеді, node.nodeValue мәліметтерге қолжетімділік үшін қолданылады, node.nodeName ағын атын береді (тег атымен сәйкес), node.attributes ағын атрибуттарына қолжетімділік береді. node.childNodes еншілес (дочерним узлам) ағындарға қолжетімділік үшін қолданылады. Осы қасиеттер ағашты рекурсивті айналып өту үшін жеткілікті.
Барлық ағындар Node классының ішкі класстарының данасы болып табылады. Олар келесідей түрде болуы мүмкін:
Атауы |
Мағынасы |
Әдіс құру үшін |
ELEMENT_NODE |
Элемент |
createElement(tagname) |
createElement(tagname) |
Атрибут |
createAttribute(name) |
TEXT_NODE |
Мәтіндік ағын |
createTextNode(data) |
CDATA_SECTION_NODE |
CDATA бөлімі |
|
ENTITY_REFERENCE_NODE |
Сілтеме мәні |
|
ENTITY_NODE |
мәні |
|
PROCESSING_INSTRUCTION_NODE |
Нұсқаулық бойынша өңдеу |
createProcessingInstruction(target, data) |
COMMENT_NODE |
Пікір |
createComment(comment) |
DOCUMENT_NODE |
Құжат |
|
DOCUMENT_TYPE_NODE |
Құжат түрі |
|
DOCUMENT_FRAGMENT_NODE |
Құжат фрагменті |
|
NOTATION_NODE |
Нотация |
|
Ағындағы бірнеше ықтимал түрлердегі обьекттен тұратын DOM құжаты ағаш болып табылады. Ағындар атрибуттар немесе деректер болуы мүмкін. Ағындарға қолжетімділікті childNodes (еншілес түйіндері), firstChild (бірінші еншілес түйіндері), lastChild (соңғы еншілес түйіндері), (ата-ана), nextSibling (келесі ағасы),previousSibling (алдыңғы ағасы).parentNode атрибуттары арқылы жүзеге асыруға болады.
Жоғарыда appendChild() әдісі арқылы айтылды. Оған insertBefore(newChild, refChild) (refChild-ге дейін newChild қою), removeChild(oldChild)
(еншілес түйіндерді өшіру), replaceChild(newChild, oldChild) (заметить oldChild на newChild) әдістерін қосуға болады. Тағыда ағындарды клондайтын (егер deep=1 берілген болса, еншілес түйіндермен бірге), cloneNode(deep) әдісі бар.
ELEMENT_NODE ағын түрі, аталғандардан басқа әдістер "жай ғана" торабының көптеген басқа әдістеріне ие. Міне олардың ішіндегі негізгілері:
tagName
Элемент түрінің аты.
getElementsByTagName(tagname)
Барлық берілген элементтерінің түрлерінің арасынан tagname атымен көрсетілген элементтерін алады.
getAttribute(attname)
attname атымен берілген атрибуттар мәнін алады.
getAttributeNode(attrname)
Обьект-ағын түріндегі attrname атымен берілген атрибутты қайтарады.
removeAttribute(attname)
attname атымен берілген атрибутты өшіреді.
removeAttributeNode(oldAttr)
oldAttr атрибутын өшіру (обьект-ағын түрінде берілген)
setAttribute(attname, value)
value жолына тең attname атрибутының мәнін белгілейді.
setAttributeNode(newAttr)
Элементке жаңа ағын-атрибут енгізеді. Егер сол атқа ие болса, ескі атрибут ауыстырылады.
Бұл жерде айта кету керек, атрибуттар элементтің аясында қайталанбауы тиіс. Олардың тәртібі, сондай-ақ XML ақпараттық моделінің тұрғысынан маңызды емес.
Жаттығу ретінде XML-ұсынуында берілген өрнектің мәнін шығаратын функцияларды құру ұсынылады.
