Python操作xml

发布时间:2019-07-29 10:29:05编辑:auto阅读(1610)

    Xml
    XML指可扩展标记语言(Extensible Markup Language)
    XML被设计用于结构化、存储和传输数据
    XML是一种标记语言,很类似于HTML
    XML没有像HTML那样具有预定义标签,需要程序员自定义标签。
    XML被设计为具有自我描述性,并且是W3C的标准
    
    XML元素
    XML的元素是指从开始标签直到结束标签的部分(均包括开始结束)。
    一个元素可以包含:
    1、其他元素
    2、文本
    3、属性
    4、或混合以上所有
    
    XML语法规则
    所有的XML元素都必须有一个开始标签和结束标签,省略结束标签是非法的。如:
    <root> content </root>
    
    XML标签对大小写敏感;比如: 下面是两个不同的标签
    <Note>this is a test1</Note>
    <note>this is a test2</note>
    
    XML文档必须有根元素。如:
    <note>
     <b>this is a test2</b> 
     <name>joy</name>
    </note>
    XML必须正确嵌套,父元素必须完全包住子元素。如:
    <note><b>this is a test2</b></note>
    XML属性值必须加引号,元素的属性值都是一个键值对形式。如:
    <book category=" Python"></book>
    注意:
    book元素中的属性category的值是python必须用引号引起来,使用单引号和双引号都可以,但是如果属性值本身包含双引号,外层就必须使用单引号;但如果包含了单引号,外层必须使用双引号
    
    XML命名规则
    名称可以包含字母、数字以及其他字符
    名称不能以数字或标点符号开头
    名称不能以字母xml或XML开始
    名称不能包含空格
    可以使用任何名称,没有保留字
    名称应该具有描述性,简短和简单,可以同时使用下划线。
    避免“-”、“.”、“:”等字符
    Xml的注释格式
    <!--注释内容-->
    
    Xml.dom解析XML
    这个DOM的解析器在解析一个XML文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后利用DOM提供的不同函数来读取该文档的内容和结构,也可以把修改过的内容写入XML文件
    book.xml
    <?xml version="1.0" encoding="utf-8" ?>
    <!--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>
    
    minidom.parse(parser=None, bufsize=None)
    该函数的作用是使用parse解析器打开xml文档,并将其解析为DOM文档,也就是内
    存中的一棵树,并得到这个DOM对象
    doc.documentElement
    获取xml文档对象,就是拿到DOM树的根。
    
    >>> from xml.dom.minidom import parse
    >>> DOMTree = parse("d:\\book.xml")#把xml解析为内存中的的一棵树
    >>> print(DOMTree)
    <xml.dom.minidom.Document object at 0x000000000241AC48>
    >>> booklist = DOMTree.documentElement#拿到树的根
    >>> print(booklist)
    <DOM Element: booklist at 0x23c6af8>
    
    doc.toxml(encoding=None)
    返回xml的文档内容
    节点的xml文档内容,只有节点对象可以调用
    
    >>> from xml.dom.minidom import parse
    >>> DOMTree = parse("d:\\book.xml")
    >>> booklist = DOMTree.documentElement
    >>> print(booklist.toxml())
    <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>
    
    doc.lastChild
    获取节点的最后一个孩子节点
    
    >>> booklist.lastChild
    <DOM Text node "'\n'">
    
    doc.firstChild
    获取节点的第一个人孩子节点
    
    >>> booklist.firstChild
    <DOM Text node "'\n  '">
    
    getElementsByTagName(name)获取节点元素
    获取xml文档中某个父节点下,具有相同节点名的节点对象的集合。返回的是list
    
    >>> from xml.dom.minidom import parse
    >>> DOMTree = parse("d:\\book.xml")
    >>> booklist = DOMTree.documentElement
    >>> books = booklist.getElementsByTagName("book")#获取标签为book的所有节点
    >>> print(books)
    [<DOM Element: book at 0x242a6d0>, <DOM Element: book at 0x23c69c8>]
    >>> print(type(books))
    <class 'xml.dom.minicompat.NodeList'>
    
    >>> from xml.dom.minidom import parse
    >>> DOMTree = parse("d:\\book.xml")
    >>> booklist = DOMTree.documentElement
    >>> print(booklist.getElementsByTagName("book")[0].getElementsByTagName("author")[0])
    <DOM Element: author at 0x242ad58>
    >>> print(booklist.getElementsByTagName("book")[0].getElementsByTagName("author")[0].toxml())
    <author>张三</author>
    hasAttribute(name)
    判断节点对象是否包含指定属性
    
    >>> from xml.dom.minidom import parse
    >>> DOMTree = parse("d:\\book.xml")
    >>> booklist = DOMTree.documentElement
    >>> if booklist.hasAttribute("type"):
    ...     print("booklist 元素存在属性type")#判断根节点booklist是否有type属性
    ... else:
    ...     print("booklist 元素不存在属性type")
    ...
    booklist 元素存在属性type
    
    Node.getAttribute(name)获取属性
    获取节点node的属性值
    >>> from xml.dom.minidom import parse
    >>> DOMTree = parse("d:\\book.xml")
    >>> booklist = DOMTree.documentElement
    >>> if booklist.hasAttribute("type"):
    ...     print("booklist存在属性type")
    ...     print(booklist.getAttribute("type"))
    ... else:
    ...     print("booklist不存在属性type")
    ...
    booklist存在属性type
    science and engineering
    node.childNodes
    返回节点node下所有子节点组成的list。
    >>> from xml.dom.minidom import parse
    >>> DOMTree = parse("d:\\book.xml")
    >>> booklist = DOMTree.documentElement
    >>> #获取所有book节点的集合
    ... books = booklist.getElementsByTagName("book")
    >>>
    >>> print("第一本书的子节点: ",books[0].childNodes)这个需要指定取列表的那个元素,必须要带上索引
    
    第一本书的子节点:  [<DOM Text node "'\n    '">, <DOM Element: title at 0x243edf0>, <DOM Text node "
    \n    '">, <DOM Element: author at 0x243ee88>, <DOM Text node "'\n    '">, <DOM Element: pageNumber
    at 0x243ef20>, <DOM Text node "'\n  '">]
    
    获取节点文本值
    #coding=utf-8
    from xml.dom.minidom import parse
    DOMTree = parse("d:\\book.xml")
    booklist = DOMTree.documentElement
    #获取所有book节点的集合
    books = booklist.getElementsByTagName("book")
    
    for book in books:
        if book.hasAttribute("category"):
            print("category is: ",book.getAttribute("categroy"))
        #先找到节点,然后再找节点下面的孩子文本节点
        title = book.getElementsByTagName("title")[0].childNodes[0].data
        author = book.getElementsByTagName("author")[0].childNodes[0].data
        pageNumber = book.getElementsByTagName("pageNumber")[0].childNodes[0].data
        print("title: ",title)
        print("title: ",author)
        print("title: ",pageNumber)
    
    node .hasChildNodes()
    判断是否有子节点
    #coding=utf-8
    import xml.dom.minidom
    from xml.dom.minidom import parse 
    #minidom解析器打开xml文档并将其解析为内存中的一棵树
    DOMTree = parse("d:\\book.xml")
    #获取xml文档对象,就是拿到树的根
    booklist = DOMTree.documentElement
    if booklist.hasAttribute("type") : 
        #判断根节点booklist是否有type属性,有则获取并打印属性的值
    
        print (u"Root element is", booklist.getAttribute("type"))
    #获取booklist对象中所有book节点的list集合
    books = booklist.getElementsByTagName("book")
    print ("books",books[0])
    print (u"book节点的个数:", books.length)
    print (books[0])
    
    if books[0].hasChildNodes():
        print (u"存在子节点:",books[0].childNodes)
    else:
        print (u"不存在子节点")
    
    xml.dom解析xml的一个实例
    movies.xml
    
    <?xml version="1.0" encoding="utf-8" ?>
    <!--this is a test about 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>
    
    示例:
    
    #coding=utf-8
    import xml.dom.minidom
    from xml.dom.minidom import parse 
    DOMTree = parse("d:\\movies.xml")
    collection = DOMTree.documentElement
    movies = collection.getElementsByTagName("movie")
    for movie in movies:
        for element in ["type","format","rating","description"]:
            node = movie.getElementsByTagName(element)[0]
            textNode = node.childNodes[0]
            print("%s节点文本是: %s" %(node,textNode.data))
    
    #coding=utf-8
    from xml.dom.minidom import parse
    import xml.dom.minidom
    # 使用minidom解析器打开 XML 文档
    DOMTree = xml.dom.minidom.parse(r"e:\\xml\\movies.xml")
    collection = DOMTree.documentElement
    if collection.hasAttribute("shelf"):
        print ("Root element : %s" % collection.getAttribute("shelf"))
    # 在集合中获取所有电影
    movies = collection.getElementsByTagName("movie")
    # 打印每部电影的详细信息
    
    for movie in movies:
        print ("*****Movie*****")
        if movie.hasAttribute("title"):
            print ("Title: %s" % movie.getAttribute("title"))
        type = movie.getElementsByTagName('type')[0]
        print ("Type: %s" % type.childNodes[0].data)
        format = movie.getElementsByTagName('format')[0]
        print ("Format: %s" % format.childNodes[0].data)
        rating = movie.getElementsByTagName('rating')[0]
        print ("Rating: %s" % rating.childNodes[0].data)
        description = movie.getElementsByTagName('description')[0]
    print ("Description: %s" % description.childNodes[0].data)
    
    xml.dom创建XML文件
    创建xml文件步骤:
    1、创建xml空文档
    2、产生根对象
    3、往根对象加数据
    4、把xml内存对象写入文件
    
    minidom.Document()创建xml空文档
    该方法用于创建一个空白的xml文档对象,并返回这个doc对象。每个xml文档都是一个Document对象,代表着内存中的DOM树。
    
    #coding=utf-8
    import xml.dom.minidom as xdm
    #在内存中创建一个空的文档
    doc = xdm.Document()
    print (doc)
    #此处创建一个根节点Managers对象
    root = doc.createElement("Managers")
    print (u"添加的xml标签为:", root.tagName)
    
    node.setAttribute(attname, value)
    该方法表示给节点添加属性-值对(Attribute) 。
    参数说明:
    attname :属性的名称
    value :属性的值
    
    import xml.dom.minidom as xdm
    #在内存中创建一个空的文档
    doc = xdm.Document()
    print(doc)
    #创建一个根节点Managers对象
    root = doc.createElement("Managers")
    print (u"添加的xml标签为:", root.tagName)
    # 给根节点root添加属性
    root.setAttribute("company","光荣之路")
    print("根节点的属性: ",root.getAttribute("company"))
    
    doc.createTextNode(data)
    给叶子节点添加文本节点
    #coding=utf-8
    import xml.dom.minidom
    #在内存中创建一个空的文档
    doc = xml.dom.minidom.Document()
    print(doc)
    #创建一个根节点Managers对象
    root = doc.createElement('company')
    print (u"添加的xml标签为:", root.tagName)
    # 给根节点root添加属性
    root.setAttribute('name', '光荣之路教育科技有限公司')
    # 给根节点添加一个叶子节点
    ceo = doc.createElement("ceo")
    #给叶子节点name设置一个文本节点,用于显示文本内容
    ceo.appendChild(doc.createTextNode("呼总"))
    print(ceo.tagName)
    
    print (u"给叶子节点添加文本节点成功")
    
    添加子节点
    #coding=utf-8
    import xml.dom.minidom
    #在内存中创建一个空的文档
    doc = xml.dom.minidom.Document()
    #创建一个根节点companys对象
    root = doc.createElement('companys')
    # 给根节点root添加属性
    root.setAttribute("name","光荣之路")
    #将根节点添加到文档对象中
    doc.appendChild(root)
    # 给根节点添加一个叶子节点
    company = doc.createElement("gloryroad")
    # 叶子节点下再嵌套叶子节点
    name = doc.createElement("Name")
    # 给节点添加文本节点
    name.appendChild(doc.createTextNode("光荣之路"))
    
    ceo = doc.createElement("CEO")
    ceo.appendChild(doc.createTextNode("吴总"))
    
    # 将各叶子节点添加到父节点company中
    # 然后将company添加到跟节点companys中
    company.appendChild(name)
    company.appendChild(ceo)
    root.appendChild(company)
    print(doc.toxml())
    
    注意父节点和子节点的关系,依赖于appendChild()函数
    以上'companys是根节点
         gloryroad是1级子节点
            name、 ceo 是2级子节点
    
    Parent.appendChild(childNode)
    把子节点childNode添加到父节点parent中
    doc.writexml()生成xml文档
    该方法用于将内存中xml文档树写入文件中,并保存到本地磁盘。上面创建的xml文档仅是存在内存中的,并未真正写入硬盘,只有调用该方法以后,才能真正将我们创建的xml文档写入本地硬盘,这时我们才能在硬盘中看见新建的xml文档。
    语法:
    Writexml(file,indent=””,addindent=””,newl=””,encoding=None)
    参数说明:
    file:要保存为的文件对象名
    Indent:根节点的缩进方式
    addindent:子节点的缩进方式
    newl: 针对新行,指明换行方式
    encoding:保存文件的编码方式
    
    示例:
    #coding=utf-8
    import xml.dom.minidom
    #在内存中创建一个空的文档
    doc = xml.dom.minidom.Document()
    #创建一个根节点companys对象
    root = doc.createElement('companys')
    # 给根节点root添加属性
    root.setAttribute("name","公司列表")
    #将根节点添加到文档对象中
    doc.appendChild(root)
    # 给根节点添加一个叶子节点
    company = doc.createElement("gloryroad")
    # 叶子节点下再嵌套叶子节点
    name = doc.createElement("Name")
    # 给节点添加文本节点
    name.appendChild(doc.createTextNode("光荣之路"))
    
    ceo = doc.createElement("CEO")
    ceo.appendChild(doc.createTextNode("吴总"))
    
    # 将各叶子节点添加到父节点company中
    # 然后将company添加到跟节点companys中
    company.appendChild(name)
    company.appendChild(ceo)
    root.appendChild(company)
    
    fp = open('d:\\company.xml','w')
    doc.writexml(fp,indent='',addindent='\t',newl='\n',encoding="utf-8")
    fp.close()
    

关键字