XML是派生于SGML(通用标记语言标准),相当于是给文本进行标记。将标签放在“<>”之中,便于解析。XML文档是层次结构的,例如如下XML文档:
<?xmlversion="1.0"encoding="ISO-8859-1"?> <!--SampleXMLDocument-test.xml--> <book> <title>SampleXMLThing</title> <author> <name><first>Ben</first><last>Smith</last></name> <affiliation>Spring</affiliation> </author> <chapternumber="1"> <title>FirstChapter</title> <para> Ithinkwidgetswaregreat.<company>Spring</company> </para> </chapter> <book>
从中可以看到xml文档的层次结构性。
通常,当使用xml文档时,会使用一个预先定义号的XML解析库,这些库通常使用下面两种方法之一来展示xml文档:树和事件。一个基于事件的解析器可以扫描文档,并在有感兴趣的内容出现的时候进行通知。例如第7章的HTMLParser例子就是一个基于事件解析器的例子。对于基于事件的解析器,可以实现编写号当文档中出现感兴趣的事情的时候,程序该做什么。
另一方面,基于树的解析器会扫描全部的文档,通过产生嵌套的数据结构来展现文档。对于一个基于树的解析器,可以在得到解析的节后后,浏览一下并挑除需要的信息。另外一个基于树的解析器的有点是,可以在把数据存入内容后进行修改,并通过系统把修改后的xml文档写到磁盘上。
Python对这两种方法都有支持。它的SAX模块可以实现基于事件的解析,它的DOM模块可以实现基于树的解析。本章只介绍DOM模块。。
#!/usr/bin/envpython #-*-coding:utf-8-*- fromxml.domimportminidom,Node defscanNode(node,level=0): msg=node.__class__.__name__ ifnode.nodeType==Node.ELEMENT_NODE: msg+=",tag:"+node.tagName print""*level*4,msg ifnode.hasChildNodes: forchildinnode.childNodes: scanNode(child,level+1) doc=minidom.parse('test.xml') scanNode(doc)
Document Comment Element,tag:book Text Element,tag:title Text Text Element,tag:author Text Element,tag:name Element,tag:first Text Text Element,tag:last Text Text Element,tag:affiliation Text Text Text Element,tag:chapter Text Element,tag:para Text Element,tag:company Text Text Text Text
ELENMENT对象表示文档中成对出现的标签。TEXT表示实际的文本,即使在处理空白内容的时候也经常建立TEXT对象。。在源代码中,parse()函数载入和解析XML文档并返回顶端节点。从这个节点开始向下访问其他的节点,就是scanNode()所做的事。
除了可以用dom库来分析xml文档,产生对象树之外,还可以反着用:生成一个对象的树,并使用库函数来写出一个xml文档。还可以从一个存在的文档中得到树后,修改它并写出结果。
#!/usr/bin/envpython fromxml.domimportminidom,Node doc=minidom.Document() doc.appendChild(doc.createComment("SampleXMLDocument")) #Generatethebook book=doc.createElement('book') doc.appendChild(book) #Thetitle title=doc.createElement('title') title.appendChild(doc.createTextNode('SampleXMLThing')) book.appendChild(title) #Theauthorsection author=doc.createElement('author') book.appendChild(author) name=doc.createElement('name') author.appendChild(name) firstname=doc.createElement('first') name.appendChild(firstname) firstname.appendChild(doc.createTextNode('Ben')) name.appendChild(doc.createTextNode('')) lastname=doc.createElement('last') lastname.appendChild(doc.createTextNode('Smith')) name.appendChild(lastname) affiliation=doc.createElement('affiliation') author.appendChild(affiliation) affiliation.appendChild(doc.createTextNode('Spring')) #Thechapter chapter=doc.createElement('chapter') book.appendChild(chapter) chapter.setAttribute('number','1') title=doc.createElement('title') chapter.appendChild(title) title.appendChild(doc.createTextNode('FirstChapter')) para=doc.createElement('para') chapter.appendChild(para) para.appendChild(doc.createTextNode('Ithinkwidgetsaregreat.')) company=doc.createElement('company') para.appendChild(company) company.appendChild(doc.createTextNode('Spring')) para.appendChild(doc.createTextNode('.')) printdoc.toprettyxml(indent='')
<?xmlversion="1.0"?> <!--SampleXMLDocument--> <book> <title>SampleXMLThing</title> <author> <name> <first>Ben</first> <last>Smith</last> </name> <affiliation>Spring</affiliation> </author> <chapternumber="1"> <title>FirstChapter</title> <para> Ithinkwidgetsaregreat. <company>Spring</company> . </para> </chapter> </book>
如果在最后,用toxml()(不带参数)替换toprettyxml(),会看到所有的文档都放到了一行里面,这就为DOM树提供一个真实的表示方法(不含任何空格),不过对人来说不美观。
XML-RPC
XML-RPC是一种与任何语言都没有关系,可以在网络上传递请求和应答的方法。它使用XML来作为基本的数据表示,但是XML-RPC用户不需要真正了解XML。
书中使用的例子与O'Reilly的市场服务有关,这个服务在2006年就关闭了,因此无法测试。。。。
原文链接:https://www.f2er.com/xml/297869.html