zoukankan      html  css  js  c++  java
  • python进阶(十七)xml(下)

    1、XML简介

    xml用到的地方:tomcat配置文件

    1) xml 指可扩展标记语言(Extensible Markup Language)

    2) xml 被设计用于结构化、存储和传输数据

    3) xml 是一种标记语言,很类似于HTML

    4) xml 没有像HTML那样具有预定义标签,需要程序员自定义标签

    5) xml 被设计为具有自我描述性,并且是W3C的标准。

     2、xml和html的区别:

    html是xml的一种特例。html里面的标签全都是已经预定义好的,都是有含义的。

    xml的数据存储和显示是分开的,存储一个文件,显示一个文件,xml不需要标签,可以自定义。

    xml:

    <bookstore>

    <book>

    <name>技术指南</name>

    </book>

    </bookstore>

    如果将以上内容放进浏览器中,浏览器中可以看到,但是不能像html显示各种样式。

    如果将以上xml也能作为网页显示,如何实现?

    3、html5实例:

    网址链接:

    http://www.w3school.com.cn/tiy/t.asp?f=html5_video_all

    代码:

    <!DOCTYPE HTML>

    <html>

    <body>

    <video width="320" height="240" controls="controls">

      <source src="/i/movie.ogg" type="video/ogg">

      <source src="/i/movie.mp4" type="video/mp4">

    Your browser does not support the video tag.

    </video>

    </body>

    </html>

    html5比html4的区别就是多了很多标签

    <h1>我的第一个标题</h1>

    <p>我的死一个段落。</p>

    <div>块

    <title>标题

    4、AJAX

    AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

    AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

    AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下。

    实际用处:比如,注册页面,用户名还未提交,就提示该用户名已被使用

    该技术的好处:不用刷新页面,重新加载页面要3s,而AJAX需要几十-几百毫秒。

    异步传输:5个步骤,谁先执行都可以,没有先后顺序,可以并发

    同步传输:按照顺序传输,1,2,3,4,5

    5、CMS(content management system,新闻发布系统)

    6、Apache和tomcat的区别:

    Apache只能做静态网页的显示。

    tomcat既能动态也能静态

    静态网页:网页一旦生成好,网页是不变的。访问的内容是一样的。

    动态网页:是根据你的请求数据和服务器的处理规则实时生成的网页。

    7、XML文档(树结构)

    XML文档形成了一种树结构,它从”根部开始”,然后扩展到“树枝”。

    XML文档必须包含根元素,该元素是所有其他元素的父元素,文芳中的所有元素形成了一棵文档树,这棵树从根开始,并扩展到树的最顶端,并且所有的元素都可以有子元素。

    <root>

    <child>

    <subchild>...</subchild>

    </child>

    </root>

    父元素拥有子元素,相同层级上的子元素成为同胞(兄弟或姐妹)。XML中所有子元素都可以有文本内容和属性,类似于HTML.

     8、XML基础知识介绍

    1) XML元素

          XML元素是指开始标签到结束标签的部分(均包括开始结束)。

          一个元素可以包含:

          1. 其他元素

          2. 文本

          3. 属性

          4. 或混合以上所有

    <!--  Edited with XML Spy v2007 (http://www.altova.com)  --> #xml注释

    <catalog>                                                              #根元素

    <cd>                                                                    #子标签

    <title>Empire Burlesque</title>  # Empire Burlesque文本节点,和空格也是文本节点,<>内的内容是element 节点

    <artist>Bob Dylan</artist>        #<title>为标签

    <country>USA</country>

    <company>Columbia</company>

    <price>10.90</price>

    <year>1985</year>

    </cd>

    <cd>...</cd>

    </catalog>

    <cd class = "classic">    #class = "classic"为属性,做辅助说明的

    <a href = "http://www.souhu.com">souhu</a>

    # href = http://www.souhu.com标签里面的内容,以=显示的叫做属性

    #点击souhu这个蓝字,会跳转到http://www.souhu.com这个网页中

         

    2) XML语法规则

          1. 所有的XML元素都必须有一个开始标签和结束标签,省略结束标签是非法的。如:

             <root>content</root>

          2. html可以少一个标签,因为浏览器会自动纠错,浏览器怎么解析html都不会崩溃。如果少一个标签,也可以解析,不过解析的内容可能和预期有差异。

             <title>光荣之路

          3. XML标签对大小写敏感;比如:下面时两个不同的标签

             <Note>this is a test1<Note>

             <note>this is a test2<note>

          4. XML文档必须有根元素。如:

    <note>

        <b>this is a test2</b>

        <name>joy</name>

    </note>

          5. XML必须正确嵌套,父元素必须完全包住子元素。如:

    <note><b>this is a test2</b><name>joy</name></note>

          6. XML属性值必须加引号,元素的属性值都是一个键值对形式。如:

    <book catgory = “Python”></book>

            注意:

                 book元素中的属性category的值是Python必须用引号引起来,使用单引号和双引号都可以,但是如果属性值本身包含双引号,外层必须使用单引号;但如果包含了单引号,外层必须使用双引号。

    9、XML命名规则

    XML元素必须遵循以下命名规则:

    1)名称可以包含字母、数字以及其他字符

    2)名称不能以数字或标点符号开头

    3)名称不能以字母xml或XML开始

    4)名称不能包含空格

    5)可以使用任何名称,没有保留字

    6)名称应该具有描述性,简短和简单,可以同时使用下划线。

    7)避免-、.、:等字符

    8)XML的注释格式为:<! -- 注释内容 -->        #和html的注释一样。

    #注释的内容不会作为浏览器显示的内容,也不会作为XML解析的内容

    10、CDATA

    CDATA(Unparsed Character Data)指的是不应由XML解析器进行解析的文本数据。

    XML解析器会将“<”(新元素的开始)和”&”(字符实体的开始)解析成具有特殊汉含义的字符。当代码中含有大量的“<”和”&”符号,可以将脚本定义为CDATA来避免这个问题,因为XML文档中的所有文本均会被解析器解析,只有CDATA部分中的所有的内容会被XML解析器忽略。

    <![CDATA[“我们自己的代码”]]>

    注意:CDATA部分不能包含字符串”]]>”,并且”]]>”之间不能有空格或折行等字符,如果包含了,会以为是CDATA的结束。也不允许嵌套CDATA部分。

    <script>

    <![CDATA[

    function test(x,y)

        { if (x<0 &&y<0) then

            {

                return 0;

            }

            else

            {                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

                return 1:

    }

    ]]>

    </script>

    11、Python解析XML三种方法

    1)SAX(simple API for XML)

    Python标准库中包含SAX解析器,SAX是用的是事件驱动模型,通过在解析XML过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。

    解析的基本过程:

    读到一个XML开始标签,就会开始一个事件,然后事件就会调用一系列的函数去处理一些事情,当读到一个结束标签时,就会触发另一个事件。所以,我们写XML文档如果有格式错误的话解析就会出错。

    这是一种流式处理,一边读一边解析,占用内存少,但速度慢。

    2) DOM(Document Object Model)

    DOM它是以对象树来表示一个XML文档的方法,使用它的好处就是你可以非常灵活的在对象中进行遍历。

    将XML数据在内存中解析成一个树,通过对树的操作来操作XML.

    由于DOM是将XML读取到内存,然后解析成一个树,如果要处理的XML文件比较大的话,就会很耗内存,所以DOM一般偏向于处理一些小的XML,(如配置文件)比较快

    占内存,但是速度快。--建议这种,因为xml现在普遍挺小,内存已经不是瓶颈。

    3) ElementTree(Object Model)

    ElementTree就像一个轻量级的DOM,具有方便而友好的API.代码的可用性好、速度快,消耗内存少。可以认为是对DOM的改进。

    支持XPATH,定位元素的一种方式。自动化定位元素的一种方式。

    12、Xml.dom解析xml

    xml.dom解析xml的思路:

    一个DOM的解析器在解析一个XML文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后利用DOM提供的不同函数来读取该文档的内容和结构,也可以把修改过的内容写入XML文件。

    <?xml version="1.0" encoding="utf-8" ?>          #xml文件头

    <!--this is a test about xml.-->                    #注释

    <booklist type="science and engineering">        #根节点

    <book category="math">

    <title>learning math</title>

    <author>张三</author>

    <pageNumber>561</pageNumber>

    </book>

    <book category="Python">

    <title>learning Python</title>

    <author>李四</author>

    <pageNumber>600</pageNumber>

    </book>

    </booklist>

    #以上是book.xml文档的内容

    13、xml.dom解析xml常用API

    1) minidom.parse(parser=None,bufsize=None)

    from xml.dom.minidom import parse   #从xml.dom.minidom模块引入解析器parse
    DOMTree = parse(r"e:ook.xml")     #minidom解析器打开xml文档并将其解析为内存中的一棵树
    print(type(DOMTree))

    #<class 'xml.dom.minidom.Document'> #xml的document对象

    #minidom.parse(parser=None,bufsize=None)

    #该函数的作用是使用parse解析器打开XML文档,并将其解析为DOM文档,也就是内存中的一棵树,并得到这个DOM对象。

    2) doc.documentElement:获取xml文档对象,就是拿到DOM树的根

    >>> from xml.dom.minidom import parse

    >>> DOMTree = parse(r"e:ook.xml")

    >>> booklist = DOMTree.documentElement

    >>> print(booklist)

    <DOM Element: booklist at 0x28471659b90>   #booklist是根节点

    3) doc.toxml:获取xml文本内容

    >>> print(DOMTree.toxml)

    <bound method Node.toxml of <xml.dom.minidom.Document object at 0x000002847165AA08>>

    >>> print(DOMTree.toxml())             #将xml中的内容除了根节点的内容都打印一下

    <?xml version="1.0" ?><!--this is a test about xml.--><booklist type="science and engineering">

    <book category="math">

    <title>learning math</title>

    <author>张三</author>

    <pageNumber>561</pageNumber>

    </book>

    <book category="Python">

    <title>learning Python</title>

    <author>李四</author>

    <pageNumber>600</pageNumber>

    </book>

    </booklist>

    >>> 

    4) has Attribute:判断是否包含属性

    >>> from xml.dom.minidom import parse  

    >>> DOMTree = parse(r"e:ook.xml")    #minidom解析器打开xml文档并将其解析为内存中的一棵树

    >>> booklist = DOMTree.documentElement  #获取xml文档对象,就是拿到树的根

    >>> print(u"DOM树的根对象:", booklist)

    #DOM树的根对象: <DOM Element: booklist at 0x28471659af8>

    >>> if booklist.hasAttribute("type"):      #判断根节点booklist是否有type属性

    ...     print(u"booklist元素存在type属性")

    ... else :

    ...     print(u"booklist元素不存在type属性")

    ...

    booklist元素存在type属性

    >>> 

    5) node.getAttrbute:获取节点node的某个属性值

    >>> from xml.dom.minidom import parse  

    >>> DOMTree = parse(r"e:ook.xml")    #minidom解析器打开xml文档并将其解析为内存中的一棵树

    >>> booklist = DOMTree.documentElement  #获取xml文档对象,就是拿到树的根

    >>> print(u"DOM树的根对象:", booklist)

    #DOM树的根对象: <DOM Element: booklist at 0x284716595a0>

    >>> if booklist.hasAttribute("type"):      #判断根节点booklist是否有type属性

    ...     print(u"Root element is",booklist.getAttribute("type"))

    ...

    Root element is science and engineering

    6) node.getElementsByTagName(name):获取节点元素

    获取XML文档中某个父节点下具有相同节点名的节点对象集合,是一个list对象。

    >>> from xml.dom.minidom import parse  

    >>> DOMTree = parse(r"e:ook.xml")    #minidom解析器打开xml文档并将其解析为内存中的一棵树

    >>> booklist = DOMTree.documentElement  #获取xml文档对象,就是拿到树的根

    >>> print(u"DOM树的根对象:", booklist)

    #DOM树的根对象: <DOM Element: booklist at 0x28471513c28>

    >>> books = booklist.getElementsByTagName("book")  #获取根节点下标签是book的

    >>> print(type(books))                                #节点对象,该返回值是个list

    <class 'xml.dom.minicompat.NodeList'>

    >>> print(books)

    [<DOM Element: book at 0x28471513a60>, <DOM Element: book at 0x28471513638>]

    >>> print(books[0])

    <DOM Element: book at 0x28471513a60>

    #上面解析xml的程序中,getElementsByTagName()函数返回的是同一父节点下所有同级(即兄弟节点)节点中相同标签的集合,这是一个list对象,所以可以使用list序列所有操作。这个时候,我们可以通过索引去拿相应的节点,也可以使用节点名称去拿相应的节点,推荐第二种方法,准确。也可以循环遍历整个返回的list。

    注意:

    就算某个父节点下没有同名的节点,该方法返回的仍是一个list,只是此时的list为空。

    7) node.childNodes:返回节点node下所有子节点组成的list

    >>> from xml.dom.minidom import parse  

    >>> DOMTree = parse(r"e:ook.xml")    #minidom解析器打开xml文档并将其解析为内存中的一棵树

    >>> booklist = DOMTree.documentElement  #获取xml文档对象,就是拿到树的根

    >>> print(u"DOM树的根对象:", booklist)

    #DOM树的根对象: <DOM Element: booklist at 0x284716595a0>

    >>> books = booklist.getElementsByTagName("book")#返回父节点下标签为book的节点

    >>> print(books[0].childNodes)           #返回第一个book节点下的所有的子节点

    [<DOM Text node "' '">, <DOM Element: title at 0x28471513898>, <DOM Text node "' '">, <DOM Element: author at 0x284715139c8>, <DOM Text node "' '">, <DOM Element: pageNumber at 0x28471513930>, <DOM Text node "' '">]

    #<DOM Text node "' '">是换行,如果不想取换行,拿到所有的子节点,不要文本节点,如何做?

    >>> print((books[0].childNodes)[1::2])       #使用切片实现

    [<DOM Element: title at 0x28471513898>, <DOM Element: author at 0x284715139c8>, <DOM Element: pageNumber at 0x28471513930>]

    8) 获取节点文本值重要!!

      1.
    from xml.dom.minidom import parse  #从xml.dom.minidom模块引入解析器parse
    DOMTree = parse(r"e:ook.xml")    #minidom解析器打开xml文档并将其解析为内存中的一棵树
    print(type(DOMTree))

    <class 'xml.dom.minidom.Document'>
    booklist = DOMTree.documentElement
    print(booklist)

    <DOM Element: booklist at 0x23b6dba2b90>
    print("*"*30)

    ******************************
    books = booklist.getElementsByTagName("book")
    d={}
    for i in range(1,6,2):
        tag_name = books[1].childNodes[i].tagName          #读取标签名字
        d[tag_name]=books[1].childNodes[i].childNodes[0].data  #读取标签值
    print(d)               #标签值(文本节点)对于标签来说是一个子节点

    {'title': 'learning Python', 'author': '李四', 'pageNumber': '600'}
    for k,v in d.items():
        print(k,v)

    title learning Python

    author 李四

    pageNumber 600

    .data读取文本节点的值,.data是文本对象的属性,必须是文本对象才可用.data

    .tagname读取标签值

    element节点在<>中,文本节点是看不见的换行和文字内容

      2.
    import xml.dom.minidom
    from xml.dom.minidom import parse  
    DOMTree = xml.dom.minidom.parse(r"e:ook.xml")   #minidom解析器打开xml文档并将其解析为内存中的一棵树
    booklist = DOMTree.documentElement  #获取xml文档对象,就是拿到树的根
    if booklist.hasAttribute("type") :  #判断根节点booklist是否有type属性,有则获取并打印属性的值
    print(u"Root element is", booklist.getAttribute("type"))  
    books = booklist.getElementsByTagName("book")  #获取booklist对象中所有book节点的list集合
    print(u"book节点的个数:", books.length)
    for book in books :
        print("*******************book*******************")
        if book.hasAttribute("category") :
            print(u"category is", book.getAttribute("category"))
    #根据节点名title拿到这个book节点下所有的title节点的集合list。
    #[0]表示第一个title标签,因为一个<book>...</book>之间可能会
    #定义多个title标签
        title = book.getElementsByTagName('title')[0]
        print("Title is", title.childNodes[0].data)
        author = book.getElementsByTagName('author')[0]
        print("author is", author.childNodes[0].data)
        pageNumber = book.getElementsByTagName('pageNumber')[0]
        print("pageNumber is", pageNumber.childNodes[0].data)

    运行结果:

    E:>python a.py

    Root element is science and engineering

    book节点的个数: 2

    *******************book*******************

    category is math

    Title is learning math

    author is 张三

    pageNumber is 561

    *******************book*******************

    category is Python

    Title is learning Python

    author is 李四

    pageNumber is 600

    9) node.haschildNodes():判断是否有子节点

    判断节点node下是否有叶子节点,如果有返回True,否则返回False。但是需要注意的是,每个节点都默认有一个文本叶子节点,所以标签后面有值,就返回True,只有当标签后没值时并且也没有叶子节点时才会返回False.

    import xml.dom.minidom

    from xml.dom.minidom import parse

    #minidom解析器打开xml文档并将其解析为内存中的一棵树

    DOMTree = xml.dom.minidom.parse(r"e:ook.xml")

    #获取xml文档对象,就是拿到树的根

    booklist = DOMTree.documentElement

    #获取booklist对象中所有book节点的list集合

    books = booklist.getElementsByTagName("book")

    print(u"book节点的个数:", books.length)

    book节点的个数: 2

    print(books[0])

    <DOM Element: book at 0x21a3acd06d0>

    if books[0].hasChildNodes():

        print(u"存在叶子节点 ", books[0].childNodes)

    else :

        print(u"不存在叶子节点")

    存在叶子节点

     [<DOM Text node "' '">, <DOM Element: title at 0x21a3acd0768>, <DOM Text node "' '">, <DOM Element: author at 0x21a3acd0800>, <DOM Text node "' '">, <DOM Element: pageNumber at 0x21a3acd0898>, <DOM Text node "' '">]

    14、xml.dom创建xml文件

    创建xml文件的步骤如下:

    1. 创建xml空文档(在内存中创建,未在本地生成一个文档)

    2. 产生根对象

    3. 往根对象里加数据

    4. 把xml内存对象写到文件

      1) minidom.Document():创建xml空白文档

    该方法用于创建一个空白的xml文档,并返回这个doc对象

    每个xml文档都是一个Document对象,代表着内存中的DOM树。

    >>> import xml.dom.minidom

    >>> doc = xml.dom.minidom.Document()   #创建空白xml文档

    >>> print(doc)

    <xml.dom.minidom.Document object at 0x00000172BBBDCAC8>

      2) doc.createElement(tagName):创建xml文档根节点

    生成xml文档节点。参数表示要生成节点的名称

    >>> import xml.dom.minidom

    >>> doc = xml.dom.minidom.Document()

    >>> print(doc)

    <xml.dom.minidom.Document object at 0x00000172BBBDCAC8>

    >>> root = doc.createElement("Manegers")

    >>> print(u"添加的xml的标签为:",root.tagName)

    添加的xml的标签为: Manegers     #同样未写到文件中,保存在内存中。

       3) node.setAttribute(attname,value):添加节点属性值对

    参数说明:

    attname:属性的名称

    value: 属性的值

    >>> root.setAttribute("company","xx科技")

    >>> value = root.getAttribute("company")

    >>> print("root元素的company的属性值是:",value)

    root元素的company的属性值是: xx科技

       4) doc.createTextNode(data):添加文本节点

    >>> ceo = doc.createElement("CEO")   #CEO节点并没有挂在根节点下

    >>> ceo.appendChild(doc.createTextNode("吴总")) #文本节点”吴总”必须依附于element节点ceo下,等价于<CEO>吴总</CEO>

    <DOM Text node "'吴总'">

    >>> print(ceo.tagName)

    CEO

     5) doc/parentNode.appendChild(node):添加子节点

    将节点node添加到文档对象doc作为文档树的根节点或者添加到父节点parentNode下作为其子节点。

    import xml.dom.minidom

    doc = xml.dom.minidom.Document()   #在内存中创建一个空的文档

    root = doc.createElement('companys')  #创建一个根节点company对象

    root.setAttribute('name', u'公司信息')   # 给根节点root添加属性

    doc.appendChild(root)               #将根节点添加到文档对象中

    company = doc.createElement('gloryroad') # 给根节点添加一个叶子节点

    name = doc.createElement("Name")   # 叶子节点下再嵌套叶子节点

    name.appendChild(doc.createTextNode(u"光荣之路教育科技公司"))#给节点添加文本节点

    ceo = doc.createElement('CEO')

    ceo.appendChild(doc.createTextNode(u'吴总'))

    company.appendChild(name)  #将各叶子节点添加到父节点company中

    company.appendChild(ceo)

    root.appendChild(company)   #然后将company添加到跟节点companys中

    print(doc.toxml())

    <?xml version="1.0" ?>

    <companys name="公司信息">

    <gloryroad>

    <Name>光荣之路教育科技公司</Name>

    <CEO>吴总</CEO>

    </gloryroad>

    </companys>

    6) doc.writexml():生成xml文档

    函数原型:

    writexml(writer,indent = “”,addindent = “”,newl = “”,encoding=None)

    该方法用于将内存中xml文档树写入文件中,并保存在本地磁盘

    参数说明:

    writer:要写的目标文件的文件对象

    indent:指明根节点缩进方式

    addindent:指明子节点缩进方式

    newl:针对新行,指明换行方式

    encoding:指明所写xml文档的编码

    import xml.dom.minidom

    doc = xml.dom.minidom.Document()   #在内存中创建一个空的文档

    root = doc.createElement('companys')  #创建一个根节点company对象

    root.setAttribute('name', u'公司信息')   # 给根节点root添加属性

    doc.appendChild(root)               #将根节点添加到文档对象中

    company = doc.createElement('gloryroad') # 给根节点添加一个叶子节点

    name = doc.createElement("Name")   # 叶子节点下再嵌套叶子节点

    name.appendChild(doc.createTextNode(u"光荣之路教育科技公司"))#给节点添加文本节点

    ceo = doc.createElement('CEO')

    ceo.appendChild(doc.createTextNode(u'吴总'))

    company.appendChild(name)  #将各叶子节点添加到父节点company中

    company.appendChild(ceo)

    root.appendChild(company)   #然后将company添加到根节点companys中

    fp = open(“e:\company.xml”,”w”,encoding = “utf-8”)

    doc.writexml(fp,indent=‘ ’,addindent=” ”,newl=” ”,encoding =”utf-8”)

    fp.close()  #indent=” ”是对根节点生效的。可以看见下面的结果根节点前有个” ”

    在e:\company.xml的文件显示的内容是:

    <?xml version="1.0" encoding="utf-8"?>

     <companys name="公司信息">

        <gloryroad>

                 <Name>光荣之路教育科技公司</Name>

                 <CEO>吴总</CEO>

          </gloryroad>

     </companys>

    15、xml.dom创建xml的完整实例

    import xml.dom.minidom

    #在内存中创建一个空的文档

    doc = xml.dom.minidom.Document()

    #创建一个根节点Managers对象

    root = doc.createElement('Managers')

    #设置根节点的属性

    root.setAttribute('company', 'xx科技')

    root.setAttribute('address', '科技软件园')

    #将根节点添加到文档对象中

    doc.appendChild(root)

    managerList = [{'name' : 'joy', 'age' : 27, 'sex' : '女'},

    {'name' : 'tom', 'age' : 30, 'sex' : '男'},

    {'name' : 'ruby', 'age' : 29, 'sex' : '女'} ]

    for i in managerList :

        nodeManager = doc.createElement('Manager')

        nodeName = doc.createElement('name')

        #给叶子节点name设置一个文本节点,用于显示文本内容

        nodeName.appendChild(doc.createTextNode(str(i['name'])))

        nodeAge = doc.createElement("age")

        nodeAge.appendChild(doc.createTextNode(str(i["age"])))

        nodeSex = doc.createElement("sex")

        nodeSex.appendChild(doc.createTextNode(str(i["sex"])))

        #将各叶子节点添加到父节点Manager中,

        #最后将Manager添加到根节点Managers中

        nodeManager.appendChild(nodeName)

        nodeManager.appendChild(nodeAge)

        nodeManager.appendChild(nodeSex)

        root.appendChild(nodeManager)

    #开始写xml文档

    fp = open('e:\Manager.xml', 'w')

    doc.writexml(fp, indent=' ', addindent=' ', newl=' ', encoding="utf-8")

    fp.close()

    Manager.xml文件的内容是:

    <?xml version="1.0" encoding="utf-8"?>

           <Managers address="科技软件园" company="xx科技">

                  <Manager>

                         <name>joy</name>

                         <age>27</age>

                         <sex>女</sex>

                  </Manager>

                  <Manager>

                         <name>tom</name>

                         <age>30</age>

                         <sex>男</sex>

                  </Manager>

                  <Manager>

                         <name>ruby</name>

                         <age>29</age>

                         <sex>女</sex>

                  </Manager>

           </Managers>

    16. Etree

    movies.xml:

    <collection shelf="New Arrivals">

    <movie title="Enemy Behind">

       <type>War, Thriller</type>

       <format>DVD</format>

       <year>2003</year>

       <rating>PG</rating>

       <stars>10</stars>

       <description>Talk about a US-Japan war</description>

    </movie>

    <movie title="Transformers">

       <type>Anime, Science Fiction</type>

       <format>DVD</format>

       <year>1989</year>

       <rating>R</rating>

       <stars>8</stars>

       <description>A schientific fiction</description>

    </movie>

    <movie title="Trigun">

       <type>Anime, Action</type>

       <format>DVD</format>

       <episodes>4</episodes>

       <rating>PG</rating>

       <stars>10</stars>

       <description>Vash the Stampede!</description>

    </movie>

    <movie title="Ishtar">

       <type>Comedy</type>

       <format>VHS</format>

       <rating>PG</rating>

       <stars>2</stars>

       <description>Viewable boredom</description>

    </movie>

    </collection>

    1). 遍历xml文件:

    import sys
    try:
        import
    xml.etree.cElementTree as ET  #as ET作为别名,是用c语言写的Etree的包,比不带c的包快,但是有可能这个包没有
    except ImportError:
        import
    xml.etree.ElementTree as ET   #如果没有,就引入不带c的包

    tree = ET.ElementTree(file='e:\movies.xml') #打开movies.xml文件
    root=tree.getroot()   #获取根节点

    #<Element 'collection' at 0x0000024FA6D96B88>
    print (root.tag)      #获取根节点的标签

    #collection
    print (root.attrib)   #获取根节点的属性值,返回值是字典
    #{'shelf': 'New Arrivals'}

    print (root.attrib[“shelf”])  #获取指定属性的属性值

    #New Arrivals


    for child_of_root in root#获取root下一级的子节点,并打印标签和属性
        print (child_of_root.tag)
        print ("********", child_of_root.attrib)

     

    #movie

    #******** {'title': 'Enemy Behind'}

    #movie

    #******** {'title': 'Transformers'}

    #movie

    #******** {'title': 'Trigun'}

    #movie

    #******** {'title': 'Ishtar'}

    print ("*"*50)

    # **************************************************
    print (root[0].tag)     #打印一个movie

    #movie
    print (root[0].text)    #第一个movie的文本节点,“打印的内容为一个回车”

                            #打印内容为一个回车
    print (root[0][0].tag)  #获取第一个movie下面的子节点的标签

    #type
    print (root[0][0].text) #获取第一个movie下面的子节点的文本内容
    # War, Thriller
    print ("*"*50)

    **************************************************
    for elem in tree.iter()#递归遍历所有子元素
        print (elem.tag, elem.attrib)
    #collection {'shelf': 'New Arrivals'}

    #movie {'title': 'Enemy Behind'}

    #type {}

    #format {}

    #year {}

    #rating {}

    #stars {}

    #description {}

    #movie {'title': 'Transformers'}

    #type {}

    #format {}

    #year {}

    #rating {}

    #stars {}

    #description {}

    #movie {'title': 'Trigun'}

    #type {}

    #format {}

    #episodes {}

    #rating {}

    #stars {}

    #description {}

    #movie {'title': 'Ishtar'}

    #type {}

    #format {}

    #rating {}

    #stars {}

    #description {}
    print ("*"*50)

    **************************************************
    for elem in tree.iterfind('movie/type'):#查找movie下一级节点中的所有type标签 ,XPATH的应用场景
        print (elem.tag, elem.attrib)
    #type {}

    #type {}

    #type {}

    #type {}
    print ("*"*50)

    **************************************************
    for elem in tree.iter(tag='stars'):#在整个树中查找标签为star的元素
       
    print (elem.tag, elem.attrib)

    #stars {}

    #stars {}

    #stars {}

    #stars {}
    print ("*"*50)

    #**************************************************
    for elem in tree.iterfind('*[@title="Ishtar"]'): #查找属性为title="Ishtar"的元素,iterfind是个迭代器
        print (elem.tag, elem.attrib)
    #movie {'title': 'Ishtar'}
    print ("*"*50)

    #**************************************************
    for elem in tree.iterfind('movie[@title="Ishtar"]'): #查找movie下属性为title="Ishtar"的元素
        print (elem.tag, elem.attrib)
    #movie {'title': 'Ishtar'}
    print ("-"*50)

    #--------------------------------------------------

    root = tree.getroot()               
    print ("root:",root[0].tag  )          #打印第一级movie元素的标签,为movie
    print ("subnode:",root[0][0].tag)      #打印第一级movie元素下的第一个子元素标签type
    print ("subnode:",root[0][1].tag )     #打印第一级movie元素下的第二个子元素标签format
    print ("subnode:",root[0][2].tag )     #打印第一级movie元素下的第三个子元素标签year
    print ("subnode:",root[0][3].tag )     #打印第一级movie元素下的第四个子元素标签rating
    print ("subnode:",root[0][4].tag )     #打印第一级movie元素下的第五个子元素标签stars
    del root[0][4] #删除第一级movie元素下的第四个子元素
    del root[0][3] #删除第一级movie元素下的第三个子元素
    del root[0][2] #删除第一级movie元素下的第二个子元素
    del root[0][1] #删除第一级movie元素下的第一个子元素

    del root[3] #删除第四个movie元素
    del root[2] #删除第三个movie元素


    for subelem in root:
       
    print (subelem.tag, subelem.attrib)  #打印四个movie元素的标签和属性

    tree.write("d:\movies.xml")  #将变更的xml文件写入到文件中

    2) 新建一个xml 文件:

    import sys
    try:
        import
    xml.etree.cElementTree as ET
    except ImportError:
        import
    xml.etree.ElementTree as ET

    a = ET.Element('elem')            #生成一个节点elem,没有文本节点
    c = ET.SubElement(a, 'child1')    #生成一个子节点下的子节点child1
    c.text = "some text"              #在子节点上添加文本节点
    d = ET.SubElement(a, 'child2')    #生成一个子节点下的子节点child2
    b = ET.Element('elem_b')          #生成一个节点elem_b,没有文本节点
    root = ET.Element('root')         #生成一个节点root
    root.extend((a, b))               #将a、b两个变量存储的节点elem和elem1添加到root节点下
    tree = ET.ElementTree(root)       #生成节点树
    root[0].set('foo', 'bar')         #设定第一个子元素的属性foo,值为bar

    tree.write("d:\test.xml")        #将xml文件内容写入到文本文件中

    3) 边读边解析xml文件

    #coding=utf-8
    import sys
    try:
        import
    xml.etree.cElementTree as ET
    except ImportError:
        import
    xml.etree.ElementTree as ET

    tree = ET.parse("d:\movies.xml")

    count = 0
    for elem in tree.iter(tag='movie'): #遍历树中的movie节点
        print (elem.tag)
        if elem[0].text == 'War, Thriller':
           
    count += 1
    print (count)



    #以下代码实现了边读文件边解析的作用,节省了内存
    count = 0
    for event, elem in ET.iterparse("d:\movies.xml")#遍历所有xml文件中的标签
        #print (elem.tag)
        if event == 'end'#检测“闭合的”(end)事件,标签关闭
            if elem.tag == 'type' and elem.text == 'War, Thriller'#标签为type,且文本内容为War, Thriller ,则count+1
                count += 1
        elem.clear() #清除元素内容,不清除则整个儿树也会在内存中,没有起到节省内存的作用。

    print (count)

    #事件
    #start 在元素打开时触发。数据和元素的子元素仍不可用。
    # end 在元素关闭时触发。所有元素的子节点,包括文本节点,现在都是可用的。
    #close 在解析完成后触发。

    小练习:

    获取database.xml文件中的hostusernameassworddatabasename的值。

    databases.xml:

    <databaselist type="database config">

    <database>

    <host>localhost</host>

    <username>root</username>

    <password>11111</password>

    <datasename>wulaoshi</datasename>

    </database>

    </databaselist>

    程序:

    from xml.dom.minidom import parse       #从xml.dom.minidom模块引入解析器parse

    DOMTree = parse(r"e:databases.xml")    #minidom解析器打开xml文档并将其解析为内存中的一棵树

    databaselist = DOMTree.documentElement

    database = databaselist.getElementsByTagName("database")

    print(database)

    [<DOM Element: database at 0x1e873fa6638>]

    d={}

    for i in range(1,8,2):

        tag_name = database[0].childNodes[i].tagName

        d[tag_name]=database[0].childNodes[i].childNodes[0].data

    print(d)

    {'host': 'localhost', 'username': 'root', 'password': '11111', 'datasename': 'wulaoshi'}

    ============================

    方法1:

    for k,v in d.items():

    print(k,v)

    host localhost

    username root

    password 11111

    datasename wulaoshi

    ==============================

    方法2:

    host = d["host"]

    username = d["username"]

    password = d["password"]

    datasename = d["datasename"]

    print(host)

    ==============================

  • 相关阅读:
    curl: (1) Protocol 'http not supported or disabled in libcurl
    线程-分为两类-用户线程和守护线程
    laypage分页插件的使用
    uploadify上传图片插件的使用
    redis安装
    php连接测试memcached
    pageY、clientY、screenY、offsetY的区别
    audio和video样式兼容
    实现剪切和复制功能
    滚动条样式
  • 原文地址:https://www.cnblogs.com/suitcases/p/11043575.html
Copyright © 2011-2022 走看看