前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >结构标记处理工具(一)、xml模块

结构标记处理工具(一)、xml模块

作者头像
狼啸风云
修改2022-09-03 22:20:06
2.9K0
修改2022-09-03 22:20:06
举报
  • 什么是xml?
  • xml和json的区别
  • xml现今的应用
  • xml的解析方式
    • xml.etree.ElementTree
    • SAX(xml.parsers.expat)
    • DOM
  • 修改xml
  • 构建xml

什么是xml? 我的理解是,xml存储着数据,是一种数据结构,结构化的存储着数据(已标签为节点的树形结构) 就像字典、列表一样,都是一种特定的数据结构。 只不过字典、列表是python解释器在内存中使用的一种数据结构,而xml是文件这种载体中的一种数据结构。 标签节点(Element):包含名字tag,属性attrib, 值text。

xml和json的区别 都说了xml是一种在文本中的一种数据结构,json是内存中数据序列化方式中的一种,序列化为json后可以写入文本中。json也可以看做一种数据结构,但是json可以表示的数据结构可以有很多如对象,列表,整数,字符串,布尔,所以说json是一种数据交换格式。

1、xml 现今的应用

由于json数据表达格式的出现,当今不同系统程序间的数据交换大多都是使用json。因为json是足够的轻量级,易读易写易解析,所以json是非常的流行。 而xml则廉颇老矣,应该很多老的系统程序还在延续使用了。因为xml解析和创建都很繁琐,解析访问修改xml的方式也很多,所以导致了xml在新开发的软件中很少使用了。大多传统软件公司还在使用,新兴互联网公司都是用json进行数据文件话,或者数据传递。

2、xml的解析方式

主要有:

  1. xml.etree.ElementTree 子模块 提供简单有效的解析xml的API以及创建xml
  2. DOM——The Document Object Model 缺点将整个xml加载到内存,占用内存大,解析慢。优点,可以任意遍历树节点。
  3. SAX——The Simple API For Xml 因为是流模式读取解析,所以缺点就是需要自己写代码对每个节点的开始、内容、结尾进行处理。不是任意的遍历,是从头到尾。

2.1、xml.etree.ElementTree

XML,可扩展标记语言,用来传输和存储数据。

 xml的文件格式:

代码语言:javascript
复制
<?xml   version="1.0"   encoding="utf-8"?>      

  <userdata   createuser="false">userdata内容  

      <dataconnection>  

          <server>localhost</server>  

          <uid>sa</uid>  

          <pwd></pwd>  

      </dataconnection>  

      <net>  

          <name>jiayuan</name>  

      </net>  

  </userdata>

xml中节点Element类的函数:

代码语言:javascript
复制
 tag                   当前节点标签名
 attrib                当前节点属性
 text                  当前节点内容
 append                添加一个子节点
 clear                 清空节点
 extend                为当前节点添加 n 个子节点
 find                  获取第一个寻找到的子节点
 findall               获取所有的子节点
 findtext              获取第一个寻找到的子节点的内容
 get                   获取当前节点的属性
 insert                在当前节点创建子节点,然后插入指定位置
 items                 获取当前节点的所有属性,和字典中的items一样,内容都是健值对
 iter                  在根据节点名称寻找所有指定的节点,并返回一个迭代器
 iterfind              获取所有指定的节点,并放在一个迭代器中
 itertext              在子孙中根据节点名称寻找所有指定的节点的内容,并返回一个迭代器
 keys                  获取当前节点的所有属性的 key
 makeelement           创建一个新节点
 remove                删除某个节点
 set                   设置当前节点属性

xml解析

代码语言:javascript
复制
1.ElementTree.XML(str)函数
代码语言:javascript
复制
from xml.etree import ElementTree as ET

with open("data.xml",'r') as file:
    #将xml文档中内容读取到strXml中
    strXml =file.read()
    #XML将字符串解析成xml特殊对象,返回xml.etree.ElementTree.Element对象,这个是根节点
    root=ET.XML(strXml)
    print(type(root))
代码语言:javascript
复制
2.ElementTree.parse("file_path")函数
代码语言:javascript
复制
#打开xml文件并且解析,返回一个xml.etree.ElementTree.ElementTree对象
tree=ET.parse("data.xml")
#获取xml的根节点
root=tree.getroot()

print(root.tag)

遍历指定的节点

代码语言:javascript
复制
 with open("data.xml",'r',encoding="utf-8") as file:
     #将xml文档中内容读取到strXml中
     strXml =file.read()
     #XML将字符串解析成xml特殊对象,返回xml.etree.ElementTree.Element对象,这个是根节点
     root=ET.XML(strXml)
     for value in root.iter("uid"):
         print(value.tag,value.text)

修改节点的内容并保存

代码语言:javascript
复制
  with open("data.xml",'r',encoding="utf-8") as file:
      #将xml文档中内容读取到strXml中
      strXml =file.read()
      #XML将字符串解析成xml特殊对象,返回xml.etree.ElementTree.Element对象,这个是根节点
      root=ET.XML(strXml)
      node=root.find("dataconnection")
      print(node)
      node.set("name","hello,xml")
  #利用ET.XML这种方法打开XML的话不能直接保存,需要借助ET.ElementTree
  #如果使用的ET.parse(filePath)打开的话,就不需要额外的创建一个ElementTree对象
       tree=ET.ElementTree(root)
       tree.write("data.xml",encoding="utf-8")
代码语言:javascript
复制
 with open("data.xml",'r',encoding="utf-8") as file:
     #将xml文档中内容读取到strXml中
     strXml =file.read()
     #XML将字符串解析成xml特殊对象,返回xml.etree.ElementTree.Element对象,这个是根节点
     root=ET.XML(strXml)
     node=root.find("dataconnection")
     root.remove(node)
 #利用ET.XML这种方法打开XML的话不能直接保存,需要借助ET.ElementTree
 #如果使用的ET.parse(filePath)打开的话,就不需要额外的创建一个ElementTree对象
     tree=ET.ElementTree(root)
     tree.write("data.xml",encoding="utf-8")

创建XML文档

代码语言:javascript
复制
 from xml.etree import ElementTree as ET
 #创建根节点
 root=ET.Element("home",{"name":"root"})
  
 #创建子节点,也可以用下面的方式创建,但只是创建,还没有加到任何节点下面
 #sub=root.makeelement("son",{"sonName":"haha"}),下面同样可以
 sub=ET.Element("son",{"sonName":"haha"})
  
 subsub=ET.Element("subson",{"subsonName":"xixi"})
 
 root.append(sub)
 
 sub.append(subsub)
 tree=ET.ElementTree(root)
 tree.write("createXml.xml")
 
 ###########结果(实际上是没有缩进的)############
 <home name="root">
     <son sonName="haha">
         <subson subsonName="xixi" />
     </son>
 </home>
代码语言:javascript
复制
  from xml.etree import ElementTree as ET
  
  root=ET.Element("home",{"name":"root"})
  #创建节点并添加到第一个参数的节点下面
  sub=ET.SubElement(root,"son",{"subName":"haha"})
  
  subsub=ET.SubElement(sub,"son",{"subName":"haha"})
  
  tree=ET.ElementTree(root)
  tree.write("createXml2.xml")
 
  #########结果(结果实际上没有缩进)###########
  <home name="root">
     <son subName="haha">
         <son subName="haha" />
     </son>
  </home>

增加缩进

代码语言:javascript
复制
 from xml.etree import ElementTree as ET
 from xml.dom import minidom
  
 def prettify(elem):
      """
      将节点转换成字符串,并添加缩进
      """
      #返回该对象的字符串表示
      rough_string = ET.tostring(elem, 'utf-8')
      print(type(rough_string))
      #从xml字符串得到dom对象
     reparsed = minidom.parseString(rough_string)
     print(type(reparsed))
     return reparsed.toprettyxml(indent="\t")

   root=ET.Element("home",{"name":"root"})
   #创建节点并添加到第一个参数的节点下面
   sub=ET.SubElement(root,"son",{"subName":"haha"})
 
   subsub=ET.SubElement(sub,"son",{"subName":"haha"})
 
   newStr=prettify(root)
 
   file=open("createXml3.xml","w",encoding="utf-8")
   file.write(newStr)
   file.close()

命名空间的使用

代码语言:javascript
复制
 from xml.etree import ElementTree as ET
 #注册命名空间
 ET.register_namespace("baidu","http://baidu.com")
  
 root=ET.Element("{http://baidu.com}home",{"name":"root"})
 #创建节点并添加到第一个参数的节点下面
 sub=ET.SubElement(root,"{http://baidu.com}son",{"{http://baidu.com}subName":"haha"})
  
 subsub=ET.SubElement(sub,"{http://baidu.com}son",{"{http://baidu.com}subName":"xixi"})
 
 tree=ET.ElementTree(root)
 tree.write("createXml4.xml")
 
 ###########结果(实际中没有缩进)##############
 <baidu:home xmlns:baidu="http://baidu.com" name="root">
     <baidu:son baidu:subName="haha">
         <baidu:son baidu:subName="xixi" />
     </baidu:son>
 </baidu:home>

2.2、SAX

使用xml.parsers.expat 使用里面的类ParserCreate()将返回一个xmlparser object,这个对象可以解析xml通过像数据流一样,一个节点一个节点的处理,处理方式是已事件触发式,即遇到节点的事件,调用事件提前做好的处理方法进行处理。 所以这种方式解析xml,需要自己定义事件的处理器,并保存每种事件处理的结果。 主要事件Event有三种: * StartElement Event * EndElement Event * CharactorData Event 要处理哪种事件,就要相应handler赋给ParserCreate 如:

代码语言:javascript
复制
import re
import datetime
from urllib import request
from xml.parsers.expat import ParserCreate
import xml.etree.ElementTree as et

with request.urlopen('https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%'
                     '20%3D%202151330&format=xml') as fp:
    wther_cont = fp.read().decode('utf-8')


# 已SAX方式解析xml
def parsexml(xml_str):
    wth_dict = dict()
    wth_dict.setdefault('city', re.search(r'Conditions for\s(?P<city>\w+),', xml_str).group('city'))  # 没找到city具体的标签或者属性,替代着用re来处理。
    wth_dict.setdefault('forecast', list())
    xml_parser = ParserCreate()  # a instance of ParserCreate, it is a xml processor.

    def start_ele(name, attrs):  # 定义start_element事件的处理
        if name == 'yweather:forecast':
            del attrs['xmlns:yweather']
            del attrs['code']
            del attrs['text']
            del attrs['day']
            # attrs['date'] = datetime.
            wth_dict['forecast'].append(attrs)

    xml_parser.StartElementHandler = start_ele  # 这里只定义了StartElement事件的处理方式
    xml_parser.Parse(xml_str)
    return wth_dict
print(parsexml(wther_cont))
  • xmlparser.Parse() 与 xmlparser.ParseFile(file) 分别是xml字符串和xml文件作为参数进行解析
  • 因为每种事件的处理,所以最好自己在定义一个类,提供事件的处理方法,和存储事件处理想要从xml中得到的数据。

2.3、DOM

提供修改主要使用xml.etree.ElementTree模块。模块的ElementTree对象提供写入和读取xml,所以修改xml后,通过ElementTree.write(file)方法将修改后的xml写入xml文件中。其实修改内容就是修改element对象的各种属性的值,如tag,attrib,text。 例如test.xml进行修改

代码语言:javascript
复制
import xml.etree.ElementTree as ET
eletree = ET.parse('./test.xml')
root_ele = eletree.getroot()
root_ele[0].attrib.pop('name')
eletree.write('./test.xml')

结果test.xml变为

代码语言:javascript
复制
<data>
    <country>   # 没有了name
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor direction="W" name="Costa Rica" />
        <neighbor direction="E" name="Colombia" />
    </country>
</data>

还可以删除某节点的子节点,element.remove(subelement)

代码语言:javascript
复制
import xml.etree.ElementTree as ET
eletree = ET.parse('./test.xml')
root_ele = eletree.getroot()
root_ele.remove(root_ele[2])
eletree.write('./test.xml')

test.xml变为

代码语言:javascript
复制
<data>
    <country>
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
    </data>

构建XML

  1. 最简单方式,直接拼接字符串
  2. 通过ElementTree对象的方法构建 a = ET.Element('a') b = ET.SubElement(a, 'b') c = ET.SubElement(a, 'c') d = ET.SubElement(c, 'd') ET.dump(a)
代码语言:javascript
复制
<a><b /><c><d /></c></a>

可以通过Element操作丰富内容 给test.xml的root节点添加一个节点

代码语言:javascript
复制
import xml.etree.ElementTree as ET
eletree = ET.parse('./test.xml')
root_ele = eletree.getroot()
haha = ET.SubElement(root_ele, 'haha')
haha.attrib.setdefault('test','testvalue')
haha.text = 'hellworld'
eletree.write('./test.xml')

结果:

代码语言:javascript
复制
<data>
    <country>
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
    <haha test="testvalue">
        hellworld
    </haha>
</data>

3、XPath

1、术语

节点(Node)

在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。

代码语言:javascript
复制
<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book>
  <title lang="en">Harry Potter</title>
  <author>J K. Rowling</author> 
  <year>2005</year>
  <price>29.99</price>
</book>

</bookstore>

上面的XML文档中的节点例子:

代码语言:javascript
复制
<bookstore> (文档节点)
<author>J K. Rowling</author> (元素节点)
lang="en" (属性节点) 

2、基本值(或称原子值,Atomic value)

基本值是无父或无子的节点。

基本值的例子:

代码语言:javascript
复制
J K. Rowling
"en"

3、项目(Item)

项目是基本值或者节点。

2、节点关系

1、父(Parent)

每个元素以及属性都有一个父。

在下面的例子中,book 元素是 title、author、year 以及 price 元素的父:

代码语言:javascript
复制
<book>
  <title>Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

2、子(Children)

元素节点可有零个、一个或多个子。

在下面的例子中,title、author、year 以及 price 元素都是 book 元素的子:

代码语言:javascript
复制
<book>
  <title>Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

3、同胞(Sibling)

拥有相同的父的节点

在下面的例子中,title、author、year 以及 price 元素都是同胞:

代码语言:javascript
复制
<book>
  <title>Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

4、先辈(Ancestor)

某节点的父、父的父,等等。

在下面的例子中,title 元素的先辈是 book 元素和 bookstore 元素:

代码语言:javascript
复制
<bookstore>

<book>
  <title>Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

</bookstore>

5、后代(Descendant)

某个节点的子,子的子,等等。

在下面的例子中,bookstore 的后代是 book、title、author、year 以及 price 元素:

代码语言:javascript
复制
<bookstore>

<book>
  <title>Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

</bookstore>

2. XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。

6、XML 实例文档

我们将在下面的例子中使用这个 XML 文档。

代码语言:javascript
复制
<?xml version="1.0" encoding="ISO-8859-1"?>

<booksto.....................................................re>

<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>

</bookstore>

7、选取节点

XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。

下面列出了最有用的路径表达式:

表达式

描述

nodename

选取此节点的所有子节点。

/

从根节点选取。

//

从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。

.

选取当前节点。

..

选取当前节点的父节点。

@

选取属性。

实例

在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:

路径表达式

结果

bookstore

选取 bookstore 元素的所有子节点。

/bookstore

选取根元素 bookstore。 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!

bookstore/book

选取属于 bookstore 的子元素的所有 book 元素。

//book

选取所有 book 子元素,而不管它们在文档中的位置。

bookstore//book

选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。

//@lang

选取名为 lang 的所有属性。

8、谓语(Predicates)

谓语用来查找某个特定的节点或者包含某个指定的值的节点。

谓语被嵌在方括号中。

实例

在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

路径表达式

结果

/bookstore/book[1]

选取属于 bookstore 子元素的第一个 book 元素。

/bookstore/book[last()]

选取属于 bookstore 子元素的最后一个 book 元素。

/bookstore/book[last()-1]

选取属于 bookstore 子元素的倒数第二个 book 元素。

/bookstore/book[position()<3]

选取最前面的两个属于 bookstore 元素的子元素的 book 元素。

//title[@lang]

选取所有拥有名为 lang 的属性的 title 元素。

//title[@lang='eng']

选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。

/bookstore/book[price>35.00]

选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。

/bookstore/book[price>35.00]/title

选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

9、选取未知节点

XPath 通配符可用来选取未知的 XML 元素。

通配符

描述

*

匹配任何元素节点。

@*

匹配任何属性节点。

node()

匹配任何类型的节点。

实例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式

结果

/bookstore/*

选取 bookstore 元素的所有子元素。

//*

选取文档中的所有元素。

//title[@*]

选取所有带有属性的 title 元素。

10、选取若干路径

通过在路径表达式中使用“|”运算符,您可以选取若干个路径。

实例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式

结果

//book/title | //book/price

选取 book 元素的所有 title 和 price 元素。

//title | //price

选取文档中的所有 title 和 price 元素。

/bookstore/book/title | //price

选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。

XPath Axes(轴)

XML 实例文档

我们将在下面的例子中使用此 XML 文档:

代码语言:javascript
复制
<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>

</bookstore>

XPath 轴

轴可定义相对于当前节点的节点集。

轴名称

结果

ancestor

选取当前节点的所有先辈(父、祖父等)。

ancestor-or-self

选取当前节点的所有先辈(父、祖父等)以及当前节点本身。

attribute

选取当前节点的所有属性。

child

选取当前节点的所有子元素。

descendant

选取当前节点的所有后代元素(子、孙等)。

descendant-or-self

选取当前节点的所有后代元素(子、孙等)以及当前节点本身。

following

选取文档中当前节点的结束标签之后的所有节点。

namespace

选取当前节点的所有命名空间节点。

parent

选取当前节点的父节点。

preceding

选取文档中当前节点的开始标签之前的所有节点。

preceding-sibling

选取当前节点之前的所有同级节点。

self

选取当前节点。

位置路径表达式

位置路径可以是绝对的,也可以是相对的。

绝对路径起始于正斜杠( / ),而相对路径不会这样。在两种情况中,位置路径均包括一个或多个步,每个步均被斜杠分割:

绝对位置路径:

代码语言:javascript
复制
/step/step/...

相对位置路径:

代码语言:javascript
复制
step/step/...

步的语法:

代码语言:javascript
复制
轴名称::节点测试[谓语]

实例

例子

结果

child::book

选取所有属于当前节点的子元素的 book 节点。

attribute::lang

选取当前节点的 lang 属性。

child::*

选取当前节点的所有子元素。

attribute::*

选取当前节点的所有属性。

child::text()

选取当前节点的所有文本子节点。

child::node()

选取当前节点的所有子节点。

descendant::book

选取当前节点的所有 book 后代。

ancestor::book

选择当前节点的所有 book 先辈。

ancestor-or-self::book

选取当前节点的所有 book 先辈以及当前节点(如果此节点是 book 节点)

child::*/child::price

选取当前节点的所有 price 孙节点。

XPath 运算符

下面列出了可用在 XPath 表达式中的运算符:

运算符

描述

实例

返回值

|

计算两个节点集

//book | //cd

返回所有拥有 book 和 cd 元素的节点集

+

加法

6 + 4

10

-

减法

6 - 4

2

*

乘法

6 * 4

24

div

除法

8 div 4

2

=

等于

price=9.80

如果 price 是 9.80,则返回 true。 如果 price 是 9.90,则返回 false。

!=

不等于

price!=9.80

如果 price 是 9.90,则返回 true。 如果 price 是 9.80,则返回 false。

<

小于

price<9.80

如果 price 是 9.00,则返回 true。 如果 price 是 9.90,则返回 false。

<=

小于或等于

price<=9.80

如果 price 是 9.00,则返回 true。 如果 price 是 9.90,则返回 false。

>

大于

price>9.80

如果 price 是 9.90,则返回 true。 如果 price 是 9.80,则返回 false。

>=

大于或等于

price>=9.80

如果 price 是 9.90,则返回 true。 如果 price 是 9.70,则返回 false。

or

price=9.80 or price=9.70

如果 price 是 9.80,则返回 true。 如果 price 是 9.50,则返回 false。

and

price>9.00 and price<9.90

如果 price 是 9.80,则返回 true。 如果 price 是 8.50,则返回 false。

mod

计算除法的余数

5 mod 2

1

XPath 实例

XML实例文档

我们将在下面的例子中使用这个 XML 文档:

"books.xml" :

代码语言:javascript
复制
<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book category="COOKING">
  <title lang="en">Everyday Italian</title>
  <author>Giada De Laurentiis</author>
  <year>2005</year>
  <price>30.00</price>
</book>

<book category="CHILDREN">
  <title lang="en">Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

<book category="WEB">
  <title lang="en">XQuery Kick Start</title>
  <author>James McGovern</author>
  <author>Per Bothner</author>
  <author>Kurt Cagle</author>
  <author>James Linn</author>
  <author>Vaidyanathan Nagarajan</author>
  <year>2003</year>
  <price>49.99</price>
</book>

<book category="WEB">
  <title lang="en">Learning XML</title>
  <author>Erik T. Ray</author>
  <year>2003</year>
  <price>39.95</price>
</book>

</bookstore>

加载 XML 文档

所有现代浏览器都支持使用 XMLHttpRequest 来加载 XML 文档的方法。

针对大多数现代浏览器的代码:

代码语言:javascript
复制
var xmlhttp=new XMLHttpRequest()

针对古老的微软浏览器(IE 5 和 6)的代码:

代码语言:javascript
复制
var xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")

选取节点

不幸的是,Internet Explorer 和其他处理 XPath 的方式不同。

在我们的例子中,包含适用于大多数主流浏览器的代码。

Internet Explorer 使用 selectNodes() 方法从 XML 文档中的选取节点:

代码语言:javascript
复制
xmlDoc.selectNodes(xpath);

Firefox、Chrome、Opera 以及 Safari 使用 evaluate() 方法从 XML 文档中选取节点:

代码语言:javascript
复制
xmlDoc.evaluate(xpath, xmlDoc, null, XPathResult.ANY_TYPE,null);

选取所有 title

下面的例子选取所有 title 节点:

代码语言:javascript
复制
/bookstore/book/title

选取第一个 book 的 title

下面的例子选取 bookstore 元素下面的第一个 book 节点的 title:

代码语言:javascript
复制
/bookstore/book[1]/title

这里有一个问题。上面的例子在 IE 和其他浏览器中输出不同的结果。

IE5 以及更高版本将 [0] 视为第一个节点,而根据 W3C 的标准,应该是 [1]。

为了解决 IE5+ 中 [0] 和 [1] 的问题,可以为 XPath 设置语言选择(SelectionLanguage)。

下面的例子选取 bookstore 元素下面的第一个 book 节点的 title:

代码语言:javascript
复制
xml.setProperty("SelectionLanguage","XPath");
xml.selectNodes("/bookstore/book[1]/title");

选取所有价格

下面的例子选取 price 节点中的所有文本:

代码语言:javascript
复制
/bookstore/book/price/text()

选取价格高于 35 的 price 节点

下面的例子选取价格高于 35 的所有 price 节点:

代码语言:javascript
复制
/bookstore/book[price>35]/price

选取价格高于 35 的 title 节点

下面的例子选取价格高于 35 的所有 title 节点:

代码语言:javascript
复制
/bookstore/book[price>35]/title

七、 pickle模块

用于序列化的两个模块

  • json:用于字符串和Python数据类型间进行转换
  • pickle: 用于python特有的类型和python的数据类型间进行转换
  • json提供四个功能:dumps,dump,loads,load
  • pickle提供四个功能:dumps,dump,loads,load

pickle可以存储什么类型的数据呢?

  1. 所有python支持的原生类型:布尔值,整数,浮点数,复数,字符串,字节,None。
  2. 由任何原生类型组成的列表,元组,字典和集合。
  3. 函数,类,类的实例

pickle模块中常用的方法有:

1. pickle.dump(obj, file, protocol=None,)

必填参数obj表示将要封装的对象

必填参数file表示obj要写入的文件对象,file必须以二进制可写模式打开,即“wb”

可选参数protocol表示告知pickler使用的协议,支持的协议有0,1,2,3,默认的协议是添加在Python 3中的协议3。   

  • Protocol version 0 is the original “human-readable” protocol and is backwards compatible with earlier versions of Python.
  • Protocol version 1 is an old binary format which is also compatible with earlier versions of Python.
  • Protocol version 2 was introduced in Python 2.3. It provides much more efficient pickling of new-style classes. Refer to PEP 307 for information about improvements brought by protocol 2.
  • Protocol version 3 was added in Python 3.0. It has explicit support for bytes objects and cannot be unpickled by Python 2.x. This is the default protocol, and the recommended protocol when compatibility with other Python 3 versions is required.
  • Protocol version 4 was added in Python 3.4. It adds support for very large objects, pickling more kinds of objects, and some data format optimizations. Refer to PEP 3154 for information about improvements brought by protocol 4.

2. pickle.load(file,*,fix_imports=True, encoding="ASCII", errors="strict")

必填参数file必须以二进制可读模式打开,即“rb”,其他都为可选参数

3. pickle.dumps(obj):以字节对象形式返回封装的对象,不需要写入文件中

4. pickle.loads(bytes_object): 从字节对象中读取被封装的对象,并返回

pickle模块可能出现三种异常:

  • PickleError:封装和拆封时出现的异常类,继承自Exception
  • PicklingError: 遇到不可封装的对象时出现的异常,继承自PickleError
  • UnPicklingError: 拆封对象过程中出现的异常,继承自PickleError
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、xml 现今的应用
  • 2、xml的解析方式
    • 2.1、xml.etree.ElementTree
      • 2.2、SAX
        • 2.3、DOM
        • 3、XPath
          • 1、术语
            • 2、节点关系
              • 6、XML 实例文档
                • 7、选取节点
                  • 8、谓语(Predicates)
                    • 9、选取未知节点
                      • 10、选取若干路径
                      • 七、 pickle模块
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档