其他XML及Schema
Posted 宣之于口
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了其他XML及Schema相关的知识,希望对你有一定的参考价值。
XML
一、XML
XML document 描述了 structure and data.
- has internal representation of a tree: DOM tree or infoset
- is divided into smaller pieces called elements
1. 基本原则
XML 有着严格的错误处理(XML has draconian error handling )
- 接受时严格
- 发送时严格
Postel’s Law: 发送时要保守;接收时要开放. 即: XML 仅满足Postel’s Law第一条
2. 基本语法
基本结构
第一行是XML声明,定义XML的版本和使用的编码
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
...
</root>
a. 规则
-
所有元素都须拥有关闭标签:
<p>This is a paragraph</p>
-
XML标签对大小写敏感:
<message> 这是正确的 </message>
-
XML必须正确的嵌套:
<b><i> Hello </i><b>
-
XML文档必须拥有一个根元素(有且仅有一个):
<root> </root>
-
XML的属性值需加引号:
<node date="08/08/2020"> </node>
-
XML可以使用空元素:
<myname/>
b. 元素 和 属性
<node date="08/08/2019"> <!-- 属性 -->
<day>08</day> <!-- 元素 -->
<month>08</month>
<year>2019</year>
</node>
因为属性引起的一些问题:
- 属性无法包含多重的值
<!-- 错误,不可重复key-->
<a type="red" type="red"></a>
- 属性无法描述树结构
- 属性不易扩展
- 属性难以阅读和维护
使用元素来描述数据,属性提供与数据无关的信息
c. namespace
XML 命名空间提供避免元素命名冲突的方法: <h:table> </h:table>
# 我们可以在一个文档中定义多个命名空间
<b:book xmlns:b="http://www.atguigu.com/xml/b" xmlns:a="http://www.atguigu.com/xml/a">
# 可以声明一个默认的命名空间, 但是要注意的是一个文档中只能有一个默认的命名空间
<book xmlns="http://www.atguigu.com/xml/b" xmlns:a="http://www.atguigu.com/xml/a">
# 属性定义的命名空间优先级高于标签, 即table的命名空间为foo2
<root xmlns:b="bar" xmlns:f="foo" xmlns="bar">
<f:table xmlns:f="foo2">
<b:tr>
<td>Apples</td>
<td>Bananas</td>
</b:tr>
</f:table>
</root>
3. DOM
XML DOM是用于获取、更改、添加和删除XML元素的标准。
a. XML DOM 节点树
DOM 将 XML 文档作为一个树形结构,而树叶被定义为节点。节点树中的节点彼此之间都有等级关系
<?xml version="1.0" encoding="UTF-8"?>
<mytext content="medium">
<title>Hallo!</title>
<content>Bye!</content>
</mytext>
b. Python 操作DOM实例
参考文档: XML DOM 获取节点值
加载并解析XML文件
import xml.dom.minidom
import sys
filename_xml = sys.argv[1]
# dom: 由解析器创建的 XML 文档
dom = xml.dom.minidom.parse(filename_xml)
获取元素值
# getElementsByTagName()方法返回包含拥有指定标签名的所有元素的节点列表,
# 其中的元素的顺序是它们在源文档中出现的顺序。
mytextNodes = dom.getElementsByTagName("mytext")
for textNode in mytextNodes:
titleNode = textNode.childNodes[1]
# childNodes[0]: 元素的第一个子元素, 文本节点
titleNodeText = titleNode.childNodes[0]
# nodeValue: 文本节点的值
print(titleNodeText.nodeValue) # Hallo!
获取属性值
mytextNodes[0].getAttribute("content");
二、XML Schema
1. RelaxNG
<?xml version="1.0" encoding="UTF-8"?>
<people>
<person age="41">
<name>
<first>Harry</first>
<last>Potter</last>
</name>
<address>4 Main Road </address>
<project type="epsrc" id="1">DeCompO </project>
<project type="eu" id="3"> TONES </project>
</person>
<person>
....
</people>
a. 紧凑语法(compact syntax)
参考文档:RELAX NG Compact Syntax Tutorial
grammar
start = people-element
people-element = element people
person-element+
person-element = element person
attribute age text ,
// 无符号: require
name-element,
// +: 出现1次或1次以上
address-element+,
// *: 出现0次或0次以上
project-element*
...
数据类型:
text
xsd:integer
xsd:date
b. XML语法(XML syntax)
参考文档: 官方文档
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/ structure/1.0">
<start>
<ref name="name-element"> </ref>
</start>
<define name="people-element">
<element name="people">
<oneOrMore>
<ref name="person-element"/>
</oneOrMore>
</element>
</define>
<define name="person-element">
</define>
...
</grammar>
其他语法:
<element name="addressBook">
<zeroOrMore>
<element name="card">
<choice>
<element name="name">
<text/>
</element>
<group>
<element name="givenName">
<text/>
</element>
<element name="familyName">
<text/>
</element>
</group>
</choice>
<optional>
<element name="note">
<text/>
</element>
</optional>
</element>
</zeroOrMore>
</element>
2. XSD
参考文档: XSD 教程
a. 元素
**简易元素(simpleContent)😗*只包含文本的元素,它不会包含任何其他的元素或属性
# 定义
<xs:element name="xxx" type="yyy"/> # 元素
<xs:attribute name="xxx" type="yyy"/> # 属性
# 默认值和固定值
<xs:element name="color" type="xs:string" default="red"/> # 默认值
<xs:element name="color" type="xs:string" fixed="red"/> # 固定值
复合元素: 包含了其他的元素及/或属性
<xs:element name="age" type="AgeType"/>
...
<xs:complexType name="AgeType">
# sequence 定义的元素必须以此顺序出现
<xs:sequence>
<xs:element name='Name' type="xs:string">
<xs:element name='DoB' type="xs:date">
</xs:sequence>
<xs:attribute name="friend" type="xs:boolean" default="true" />
<xs:attribute name="phone" type="xs:string" />
</xs:complexType>
带有混合内容的复合类型
<letter>
Dear Mr.
<name>John Smith</name>.
Your order
<orderid>1032</orderid>
</letter>
为了让字符数据可以出现在 “letter” 的子元素之间,mixed 属性必须被设置为 “true”
<xs:element name="letter">
<xs:complexType mixed="true">
...
</xs:complexType>
</xs:element>
b. 限定(restriction)
限定(restriction)用于为 XML 元素或者属性定义可接受的值。对 XML 元素的限定被称为 facet
限定 | 描述 |
---|---|
enumeration | 定义可接受值的一个列表 |
pattern | 定义可接受的字符的精确序列 |
length | 定义所允许的字符或者列表项目的精确数目 |
maxInclusive | 定义数值的上限。所允许的值必须小于或等于此值 |
maxLength | 定义所允许的字符或者列表项目的最大数目 |
minInclusive | 定义数值的下限。所允许的值必需大于或等于此值 |
minLength | 定义所允许的字符或者列表项目的最小数目 |
范围约束: 限定值的范围为minInclusive
- maxInclusive
<!-- <age>4</age> -->
<xs:element name="age">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="3"/>
<xs:maxInclusive value="7"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
枚举约束: 把 XML 元素的内容限制为一组可接受的值
<xs:element name="car">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Audi"/>
<xs:enumeration value="Golf"/>
<xs:enumeration value="BMW"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
模式约束: 使用正则表达式,把 XML 元素的内容限制定义为一系列可使用的数字或字母
<xs:element name="letter">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-z]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
c. 扩展(extension)
举例说明: 通过添加三个元素,对一个已有的 complexType 元素进行扩展
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="employee" type="fullpersoninfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="fullpersoninfo">
<xs:complexContent>
<xs:extension base="personinfo">
<xs:sequence>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>)
4. 对比
RelaxNG: grammar-based
- simple/flexible: easy to use
- no mechanism for manipulating datatypes, lists, unions,… [however, can borrow this from XSD]
- no restrictions & extension, no (non-atomic) types
-
in a document, an element of a type derived by restriction from Y can be used in place of an element of type Y
-
this can make writing complex schemas easier & leaves information in IR!
-
but this means that a validating XML parser has to manage a schema’s type hierarchy
-
DTDs and XML Schema (XSD): rule-based
- XML Schema has restrictions on expressing constraints on content models
- e.g., XML Element Declarations Consistent constraint
- applications can do error-checking in a format independent way
三、Schematron
一、基本概念
Schematron 文档基本上是一组应用于 XML 数据的约束
断言 (asserts)
对应用于实例文档的特定条件进行测试,实例文档要想有效,所有断言的计算结果都必须是 true
<assert test = "count(//b/(*|text())) = 0">
Error: b elements must be empty
</assert>
报告 (reports)
在这种情况下也对应用的条件进行测试。但是,测试的意义与断言的意义正好相反。如果测试结果是 true,那么文档将处于无效状态
<report test = "count(//b/(*|text()))!= 0">
Error: b elements must be empty
</report>
example: “At least 1 person for each family”
<pattern>
<rule context="person">
<let name="L" value="@LastName"/>
<report test="count(//family[@name = $L]) = 0">
There has to be a family for each person mentioned,
but <value-of select="$L"/> has none!
</report>
</rule>
</pattern>
<PList>
<person FirstName="Bob" LastName="Builder"/>
<person FirstName="Bill" LastName="Bolder"/>
<person FirstName="Bob" LastName="Milder"/>
<family name="Builder" town="Manchester"/>
<family name="Bolder" town="Bolton"/>
</PList>
# output
Severity: error
Description: There has to be a family for each person mentioned, but Milder has none!
四、PSVI
参考文档: Post-Schema-Validation Infoset
架构验证后信息集(Post-Schema-Validation Infoset)
基于 Schema 的验证完成后,可以按照 Schema 所隐含的数据模型来表达文档的结构与内容。XML Schema 数据模型包括:
- 树形结构及数据内容
- 标签(类型注释)
- 添加了默认值(元素和属性)
- 有效性或无效性结果
这些信息的集合即为 Schema 既验信息集 (Post-Schema-Validation Infoset (PSVI)). 对于有效的 XML,PSVI 给它赋以特定的“类型”,从而便于以对象方式来处理整个文档,并应用面向对象程序设计(OOP)范式。
1. 特点说明
假设P1和P2相同:
-
D1和D2可以不相同, 存在结构相同但某些元素上的属性不同
-
S1与S2可以不相同, S1和S2指定不同的默认值。 那么它们都不是相似/相同/等价的
2. 举例说明:
以上是关于其他XML及Schema的主要内容,如果未能解决你的问题,请参考以下文章
rest-assured之Schema validation(包括JSON Schema validation及Xml Schema validation)