libxml2(schema)的简单使用

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/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值