xml schema是用来定义xml的合法构建模块,通过xml schema就能在接收到xml消息时,判定消息是否合法,从而保障xml信息安全。
从Index of /sources (xmlsoft.org)可以下载libxml2的源码
我用的是2.9.12
创建一个xml schema文件
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Address">
<xs:complexType>
<xs:sequence>
<xs:element name="Recipient" type="xs:string"/>
<xs:element name="House" type="xs:string"/>
<xs:element name="Street" type="xs:string"/>
<xs:element name="Town" type="xs:string"/>
<xs:element name="County" type="xs:string" minOccurs="0"/>
<xs:element name="PostCode" type="xs:unsignedInt"/>
<xs:element name="Country" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="IN"/>
<xs:enumeration value="DE"/>
<xs:enumeration value="ES"/>
<xs:enumeration value="UK"/>
<xs:enumeration value="US"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
创建与之对应的xml文件
<?xml version="1.0" encoding="utf-8"?>
<Address
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="address.xsd">
<Recipient>Mr. Walter C. Brown</Recipient>
<House>good</House>
<Street>Featherstone Street</Street>
<Town>LONDON</Town>
<PostCode>8</PostCode>
<Country>UK</Country>
</Address>
利用libxml2检查xml是否合法
命令行方式
xmllint --schema address.xsd address.xml
代码实现
(我这里用的是xmlReadMemory从内存中读取信息,也可以用xmlReadFile直接读文件,具体根据实际场景进行选择)
#include <stdio.h>
#include <string.h>
#include <libxml/xmlversion.h>
#include <libxml/parser.h>
#include <libxml/xmlschemas.h>
int validateXmlFile()
{
int iError = 0;
xmlDocPtr pDoc;
xmlDocPtr pSchemaDoc;
xmlSchemaParserCtxtPtr pSchemaCtxt;
xmlSchemaPtr pSchema;
xmlSchemaValidCtxtPtr pValidCtxt;
char * xmlFilename = "./address.xml";
char * schemaFilename = "./address.xsd";
printf("Schema file : -------%s \n", schemaFilename);
printf("XML file : --------%s \n", xmlFilename);
//pDoc = xmlReadFile(xmlFilename, NULL, XML_PARSE_NONET);//直接读文件的方式
char xml_buf[1024] = {};
FILE *xml_fd = fopen(xmlFilename, "r");
if (xml_fd)
{
fread(xml_buf, 1, 1024, xml_fd);
fclose(xml_fd);
}
pDoc = xmlReadMemory(xml_buf, (int)strlen(xml_buf), NULL, NULL, XML_PARSE_NONET);
if (!pDoc)
return -1;
//pSchemaDoc = xmlReadFile(schemaFilename, NULL, XML_PARSE_NONET);//直接读文件的方式
char xsd_buf[1024] = {};
FILE *xsd_fd = fopen(schemaFilename, "r");
if (xsd_fd)
{
fread(xsd_buf, 1, 1024, xsd_fd);
fclose(xsd_fd);
}
pSchemaDoc = xmlReadMemory(xsd_buf, (int)strlen(xsd_buf), NULL, NULL, XML_PARSE_NONET);
if (!pSchemaDoc)
return -2;
pSchemaCtxt = xmlSchemaNewDocParserCtxt(pSchemaDoc);
if (!pSchemaCtxt)
return -3;
pSchema = xmlSchemaParse(pSchemaCtxt);
if (!pSchema)
return -4;
pValidCtxt = xmlSchemaNewValidCtxt(pSchema);
if(!pValidCtxt)
return -5;
// Attempting to validate xml with schema
xmlSchemaFreeParserCtxt(pSchemaCtxt);
xmlFreeDoc(pSchemaDoc);
iError = xmlSchemaValidateDoc(pValidCtxt, pDoc);
if (iError == 0)
printf("Document in %s is valid \n", xmlFilename);
else
printf("Document in %s is NOT valid \n", xmlFilename);
xmlSchemaFree(pSchema);
xmlFreeDoc(pDoc);
return 0;
}
int main(int argc, char* argv[])
{
printf("%s\n", LIBXML_DOTTED_VERSION);
validateXmlFile();
return 0;
}
我是在安装目录写的demo
编译:gcc main.c -o main -I ./include/libxml2 -l xml2 -L ./lib/