其他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)

advanced-day17-XML,DTD约束,schema约束及枚举,注解

XML的Schema约束

XML Schema简介

JSON解析器之json schema校验及代码实现

xml