用xerces-c来进行xml schema校验「建议收藏」

用xerces-c来进行xml schema校验

大家好,又见面了,我是全栈君。

在xerces-c的官方站点上有文章指引说明是怎样进行xml schema校验。

http://xerces.apache.org/xerces-c/schema-3.html

给出的样例代码:

// Instantiate the DOM parser.
XercesDOMParser parser;
parser.setDoNamespaces(true);
parser.setDoSchema(true);
parser.parse(xmlFile);

但。样例代码根本不起不论什么作用。

在调用XercesDOMParser::parse之前,还有两件事情要做:

1.调用XercesDOMParser::setValidationScheme来设置校验计划

parser.setValidationScheme( XercesDOMParser::Val_Auto);

parser.setValidationScheme( XercesDOMParser::Val_Always);

2.要调用XercesDOMParser::setErrorHandler, 当中參数必须是ErrorHandler类或子类的对象。

看以下样例

address.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>EC1Y 8SY</PostCode> <Country>UK</Country></Address>

address.xsd:

<?xml version="1.0" encoding="utf-8"?

><xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <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>

new_address.cpp:

#include <stdio.h>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/sax/SAXException.hpp>
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMLSException.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>

using namespace XERCES_CPP_NAMESPACE;

class SchemaErrorHandler : public DefaultHandler
{
	public:
		SchemaErrorHandler() {}
		~SchemaErrorHandler() {}

	void warning(const SAXParseException& exc)
	{
		printf( "warn in line:%lu, col:%lu, %s\n", 
				exc.getLineNumber(), exc.getColumnNumber(),
				XMLString::transcode( exc.getMessage()) );
	}

    void error(const SAXParseException& exc)
	{
		printf( "error in line:%lu, col:%lu, %s\n", 
				exc.getLineNumber(), exc.getColumnNumber(),
				XMLString::transcode( exc.getMessage()) );
	}

    void fatalError(const SAXParseException& exc)
	{
		printf( "fatal in line:%lu, col:%lu, %s\n", 
				exc.getLineNumber(), exc.getColumnNumber(),
				XMLString::transcode( exc.getMessage()) );
	}

    void resetErrors()
	{
		printf( "nothing\n" );
	}
};

int main(int argc, char* argv[] )
{
	if ( argc < 2 )
	{
		printf( "must specify a file\n" );
		return -1;
	}

	XMLPlatformUtils::Initialize();

	XercesDOMParser parser;
	SchemaErrorHandler handler;
	try
	{
		parser.setErrorHandler( &handler );
		parser.setDoNamespaces(true);
		parser.setDoSchema(true);
		//parser.setValidationScheme( XercesDOMParser::Val_Auto);
		parser.parse( argv[1] );
	} catch ( SAXException& e )
	{
		printf( "msg:%s\n", XMLString::transcode(e.getMessage() ) );
		return -2;
	}
	catch ( XMLException& e )
	{
		printf( "code:%d, msg:%s\n", e.getCode(), XMLString::transcode( e.getMessage() ) );
		return -3;
	}
	catch (	DOMException& e )
	{
		printf( "code:%d, msg:%s\n", e.code, e.msg );
		return -4;
	}

	return 0;
}

能够看到这里的代码凝视掉了这一行:

//parser.setValidationScheme( XercesDOMParser::Val_Auto);

编译执行:

[xuzhina@localhost sample]$ g++ -g -o new_address new_address.cpp -lxerces-c
[xuzhina@localhost sample]$ ./new_address address.xml 
[xuzhina@localhost sample]$ 

//parser.setValidationScheme( XercesDOMParser::Val_Auto);

打开,但凝视掉

parser.setErrorHandler( &handler );

编译执行:

[xuzhina@localhost sample]$ g++ -g -o new_address new_address.cpp -lxerces-c
[xuzhina@localhost sample]$ ./new_address address.xml 
[xuzhina@localhost sample]$ 

parser.setErrorHandler( &handler );

打开,编译执行:

[xuzhina@localhost sample]$ ./new_address address.xml 
error in line:8, col:31, value 'EC1Y 8SY' does not match regular expression facet '[+\-]?[0-9]+'

执行一下xmllint,对照一下结果:

[xuzhina@localhost sample]$ xmllint --schema address.xsd address.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>EC1Y 8SY</PostCode>
	<Country>UK</Country>
</Address>
address.xml:8: element PostCode: Schemas validity error : Element 'PostCode': 'EC1Y 8SY' is not a valid value of the atomic type 'xs:unsignedInt'.
address.xml fails to validate

PS:

在xml schema中,string是兼容其他类型,比方在House标签的内容写上数字,比方49,不管xmllint, 还是xerces都不会报这个标签的值有问题。

以前为这个问题折腾一个下午。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116169.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • AlertDialog的几种用法

    AlertDialog的几种用法xml代码:java代码:

    2022年7月2日
    21
  • vue 富文本编辑框_基于vue的富文本编辑器

    vue 富文本编辑框_基于vue的富文本编辑器1、下载插件npmiwangeditor–save插件官网地址:https://www.wangeditor.com/2、封装富文本组件<templatelang=”html”><divclass=”editor”><!–<divref=”toolbar”class=”toolbar”></div>–><divref=”editor”class=”text”></div

    2022年10月9日
    0
  • 均值归一化详解_matlab数据归一化

    均值归一化详解_matlab数据归一化数据归一化[TOC]将所有的数据映射到同一尺度。​首先,为什么需要数据归一化?举个简答的例子。样本间的距离时间所主导,这样在样本1以[1,200]输入到模型中去的时候,由于200可能会直接忽略到1的存在,因此我们需要将数据进行归一化。比如将天数转换为占比1年的比例,200/365=0.5479,100/365=0.2740。一、最值归一化最值归一化(Nor…

    2022年10月11日
    0
  • 2021年美赛A题思路与程序–已更新

    2021年美赛A题思路与程序–已更新美赛第一小题部分程序%预测的菌群的数量clc;clearall;y=input(‘请输入数据’);n=length(y);yy=ones(n,1);yy(1)=y(1);fori=2:nyy(i)=yy(i-1)+y(i)endB=ones(n-1,2);fori=1:(n-1)B(i,1)=-(yy(i)+yy(i+1))/2;B(i,2)=1;endBT=B’;forj=1:(n-1)YN(j)=y(j+1);endYN=YN’;A=inv(BT

    2022年6月6日
    46
  • class.getclassloader()_javaassist

    class.getclassloader()_javaassist全屏java.lang.Class.getClassLoader()方法返回的类加载器的类。一些实现可能使用null表示引导类加载器。如果这个类是由引导类加载器加载的方法在这样的实现将返回null。声明以下是java.lang.Class.getClassLoader()方法的声明publicClassLoadergetClassLoader()参数NA返回值此方法返回加载此对象所表示的类或接…

    2022年5月3日
    62
  • springboot线程池的配置使用[通俗易懂]

    springboot线程池的配置使用[通俗易懂]我们都知道,java中有ThreadPoolExecutor提供的线程池服务,非常好用。可以有效的解决了一些异步业务,提高系统性能。但是java中配置和使用线程池有点繁琐,而在springboot中,线程池的配置简直就是轻而易举。下面直接上干货。springboot中主要使用配置类来配置线程池@Async注解可以使用配置好的线程池下面我们来详细看一下配置和使用的过程1、配置线程池主要使用…

    2022年6月28日
    48

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号