使用 xmllint + schema 校验 xml 文档
XML 校验工具的作用就是检查我们写的 XML 源文件是否符合所声明要遵循的规范,xmllint 就是一款很实用的 XML 校验器,下面通过一个例子,演示一下 xmllint 如何结合 schema 对xml 文档进行校验。本文未涉及 schema 的语法介绍。
首先建立一份 xml 文档,命名为 po.xml,其内容如下:
<?xml version ="1.0" ?>
<purchaseOrder orderDate ="1999-10-20" >
<shipTo country ="US" >
<name> Alice Smith </name>
<street> 123 Maple Street </street>
<city> Mill Valley </city>
<state> CA </state>
<zip> 90952 </zip>
</shipTo>
<billTo country ="US" >
<name> Robert Smith </name>
<street> 8 Oak Avenue </street>
<city> Old Town </city>
<state> PA </state>
<zip> 95819 </zip>
</billTo>
<comment> Hurry, my lawn is going wild! </comment>
<items>
<item partNum ="872-AA" >
<productName> Lawnmower </productName>
<quantity> 1 </quantity>
<USPrice> 148.95 </USPrice>
<comment> Confirm this is electric </comment>
</item>
<item partNum ="926-AA" >
<productName> Baby Monitor </productName>
<quantity> 1 </quantity>
<USPrice> 39.98 </USPrice>
<shipDate> 1999-05-21 </shipDate>
</item>
</items>
</purchaseOrder>
<purchaseOrder orderDate ="1999-10-20" >
<shipTo country ="US" >
<name> Alice Smith </name>
<street> 123 Maple Street </street>
<city> Mill Valley </city>
<state> CA </state>
<zip> 90952 </zip>
</shipTo>
<billTo country ="US" >
<name> Robert Smith </name>
<street> 8 Oak Avenue </street>
<city> Old Town </city>
<state> PA </state>
<zip> 95819 </zip>
</billTo>
<comment> Hurry, my lawn is going wild! </comment>
<items>
<item partNum ="872-AA" >
<productName> Lawnmower </productName>
<quantity> 1 </quantity>
<USPrice> 148.95 </USPrice>
<comment> Confirm this is electric </comment>
</item>
<item partNum ="926-AA" >
<productName> Baby Monitor </productName>
<quantity> 1 </quantity>
<USPrice> 39.98 </USPrice>
<shipDate> 1999-05-21 </shipDate>
</item>
</items>
</purchaseOrder>
然后为 po.xml 写的 schema 文件,取名为 po.xsd,内容如下:
<xsd:schema xmlns:xsd ="http://www.w3.org/2001/XMLSchema" >
<xsd:annotation>
<xsd:documentation xml:lang ="en" >
Purchase order schema for Example.com.
Copyright 2000 Example.com. All rights reserved.
</xsd:documentation>
</xsd:annotation>
<xsd:element name ="purchaseOrder" type ="PurchaseOrderType" />
<xsd:element name ="comment" type ="xsd:string" />
<xsd:complexType name ="PurchaseOrderType" >
<xsd:sequence>
<xsd:element name ="shipTo" type ="USAddress" />
<xsd:element name ="billTo" type ="USAddress" />
<xsd:element ref ="comment" minOccurs ="0" />
<xsd:element name ="items" type ="Items" />
</xsd:sequence>
<xsd:attribute name ="orderDate" type ="xsd:date" />
</xsd:complexType>
<xsd:complexType name ="USAddress" >
<xsd:sequence>
<xsd:element name ="name" type ="xsd:string" />
<xsd:element name ="street" type ="xsd:string" />
<xsd:element name ="city" type ="xsd:string" />
<xsd:element name ="state" type ="xsd:string" />
<xsd:element name ="zip" type ="xsd:decimal" />
</xsd:sequence>
<xsd:attribute name ="country" type ="xsd:NMTOKEN"
fixed ="US" />
</xsd:complexType>
<xsd:complexType name ="Items" >
<xsd:sequence>
<xsd:element name ="item" minOccurs ="0" maxOccurs ="unbounded" >
<xsd:complexType>
<xsd:sequence>
<xsd:element name ="productName" type ="xsd:string" />
<xsd:element name ="quantity" >
<xsd:simpleType>
<xsd:restriction base ="xsd:positiveInteger" >
<xsd:maxExclusive value ="100" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name ="USPrice" type ="xsd:decimal" />
<xsd:element ref ="comment" minOccurs ="0" />
<xsd:element name ="shipDate" type ="xsd:date" minOccurs ="0" />
</xsd:sequence>
<xsd:attribute name ="partNum" type ="SKU" use ="required" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<!-- Stock Keeping Unit, a code for identifying products -->
<xsd:simpleType name ="SKU" >
<xsd:restriction base ="xsd:string" >
<xsd:pattern value ="\d{3}-[A-Z]{2}" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
<xsd:annotation>
<xsd:documentation xml:lang ="en" >
Purchase order schema for Example.com.
Copyright 2000 Example.com. All rights reserved.
</xsd:documentation>
</xsd:annotation>
<xsd:element name ="purchaseOrder" type ="PurchaseOrderType" />
<xsd:element name ="comment" type ="xsd:string" />
<xsd:complexType name ="PurchaseOrderType" >
<xsd:sequence>
<xsd:element name ="shipTo" type ="USAddress" />
<xsd:element name ="billTo" type ="USAddress" />
<xsd:element ref ="comment" minOccurs ="0" />
<xsd:element name ="items" type ="Items" />
</xsd:sequence>
<xsd:attribute name ="orderDate" type ="xsd:date" />
</xsd:complexType>
<xsd:complexType name ="USAddress" >
<xsd:sequence>
<xsd:element name ="name" type ="xsd:string" />
<xsd:element name ="street" type ="xsd:string" />
<xsd:element name ="city" type ="xsd:string" />
<xsd:element name ="state" type ="xsd:string" />
<xsd:element name ="zip" type ="xsd:decimal" />
</xsd:sequence>
<xsd:attribute name ="country" type ="xsd:NMTOKEN"
fixed ="US" />
</xsd:complexType>
<xsd:complexType name ="Items" >
<xsd:sequence>
<xsd:element name ="item" minOccurs ="0" maxOccurs ="unbounded" >
<xsd:complexType>
<xsd:sequence>
<xsd:element name ="productName" type ="xsd:string" />
<xsd:element name ="quantity" >
<xsd:simpleType>
<xsd:restriction base ="xsd:positiveInteger" >
<xsd:maxExclusive value ="100" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name ="USPrice" type ="xsd:decimal" />
<xsd:element ref ="comment" minOccurs ="0" />
<xsd:element name ="shipDate" type ="xsd:date" minOccurs ="0" />
</xsd:sequence>
<xsd:attribute name ="partNum" type ="SKU" use ="required" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<!-- Stock Keeping Unit, a code for identifying products -->
<xsd:simpleType name ="SKU" >
<xsd:restriction base ="xsd:string" >
<xsd:pattern value ="\d{3}-[A-Z]{2}" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
使用 xmllint 对 po.xml 文件进行校验:
$ xmllint -schema po.xsd po.xml
如果无出错信息,就说明校验通过了。
校验1个xml是否格式正确,可用如下命令:
$xmllint example.xml