一、详细的xml解析
XML(eXtensible Markup Language)即可扩展标记语言,它与HTML一样,都是处于SGML,标准通用语言。Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具。扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用。
XML与Access,Oracle和SQL Server等数据库不同,数据库提供了更强有力的数据存储和分析能力,例如:数据索引、排序、查找、相关一致性等,XML仅仅是展示数据。事实上XML与其他数据表现形式最大的不同是:他极其简单。这是一个看上去有点琐细的优点,但正是这点使XML与众不同。
XML的简单使其易于在任何应用程序中读写数据,这使XML很快成为数据交换的唯一公共语言,虽然不同的应用软件也支持其它的数据交换格式,但不久之后他们都将支持XML,那就意味着程序可以更容易的与Windows、Mac OS, Linux以及其他平台下产生的信息结合,然后可以很容易加载XML数据到程序中并分析他,并以XML格式输出结果。
XML的前身是SGML(The Standard Generalized Markup Language),是自IBM从60年代就开始发展的GML(Generalized Markup Language)
同HTML一样, XML(可扩展标识语言)是通用标识语言标准(SGML)的一个子集,它是描述网络上的数据内容和结构的标准。尽管如此,XML不象HTML,HTML仅仅提供了在页面上显示信息的通用方法(没有上下文相关和动态功能),XML则对数据赋予上下文相关功能,它继承了SGML的大部分功能,却使用了不太复杂的技术。.
为了使得SGML显得用户友好,XML重新定义了SGML的一些内部值和参数,去掉了大量的很少用到的功能,这些繁杂的功能使得SGML在设计网站时显得复杂化。XML保留了SGML的结构化功能,这样就使得网站设计者可以定义自己的文档类型,XML同时也推出一种新型文档类型,使得开发者也可以不必定义文档类型。
因为XML是W3C制定的,XML的标准化工作由W3C的XML工作组负责,该小组成员由来自各个地方和行业的专家组成,他们通过email交流对XML标准的意见,并提出自己的看法(www.w3.org/TR/WD-xml)。因为XML是个公共格式,(它不专属于任何一家公司),你不必担心XML技术会成为少数公司的盈利工具,XML不是一个依附于特定浏览器的语言
XML(可扩展标记语言)是从称为SGML(标准通用标记语言)的更加古老的语言派生出来的。SGML的主要目的是定义使用标签来表示数据的标记语言的语法。
标签由包围在一个小于号(<)和一个大于号(>)之间的文本组成,例如<tag>。起始标签(start tag)表示一个特定区域的开始,例如<start>;结束标签(end tag)定义了一个区域的结束,除了在小于号之后紧跟着一个斜线(/)外,和起始标签基本一样,例如</end>。SGML还定义了标签的特性(attribute),它们是定义在小于号和大于号之间的值,例如<img src="picture.jpg">中的src特性。如果你觉得它看起来很熟悉的话,应该知道,基于SGML的语言的最著名实现就是原始的HTML。
SGML常用来定义针对HTML的文档类型定义(DTD),同时它也常用于编写XML的DTD。SGML的问题就在于,它允许出现一些奇怪的语法,这让创建HTML的解析器成为一个大难题:
1某些起始标签不允许出现结束标签,例如HTML中<img>标签。包含了结束标签就会出现错误。
2某些起始标签可以选择性出现结束标签或者隐含了结束标签,例如HTML中标签,当出现另一个标签或者某些其他标签时,便假设在这之前有一个结束标签。
3某些起始标签要求必须出现结束标签,例如HTML中<script>标签。
4标签可以以任何顺序嵌套。即使结束标签不按照起始标签的逆序出现也是允许的,例如,This is a sample string是正确的。
5某些特性要求必须包含值,例如<img src="picture.jpg">中的src特性。
6某些特性不要求一定有值,例如[td]中的nowrap特性。
7定义特性的两边有没有加上双引号都是可以的,所以<img src="picture.jpg">和<img src=picture.jpg>都是允许的。
这些问题使建立一个SGML语言的解析器变成了一项艰巨的任务。判断何时应用以上规则的困难导致了SGML语言的定义一直停滞不前。以这些问题作为出发点,XML逐渐步入我们的视野。
XML去掉了之前令许多开发人员头疼的SGML的随意语法。在XML中,采用了如下的语法:
8任何的起始标签都必须有一个结束标签。
9可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/),例如<tag/>。XML解析器会将其翻译成<tag></tag>。
10标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,例如this is a sample string。这好比是将起始和结束标签看作是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号的。
11所有的特性都必须有值。
12所有的特性都必须在值的周围加上双引号。
这些规则使得开发一个XML解析器要简便得多,而且也除去了解析SGML中花在判断何时何地应用那些奇怪语法规则上的工作。仅仅在XML出现后的前六年就衍生出多种不同的语言,包括MathML、SVG、RDF、RSS、SOAP、XSLT、XSL-FO,而同时也将HTML改进为XHTML。
如果需要关于SGML和XML具体技术上的对比,请查看W3C的注解,位于:http://www.w3. org/TR/NOTE-sgml-xml.html
如今,XML已经是世界上发展最快的技术之一。它的主要目的是使用文本以结构化的方式来表示数据。在某些方面,XML文件也类似于数据库,提供数据的结构化视图。这里是一个XML文件的例子:
每个XML文档都由XML序言开始,在前面的代码中的第一行便是XML序言,<?xml version="1.0"?>。这一行代码会告诉解析器和浏览器,这个文件应该按照前面讨论过的XML规则进行解析。第二行代码,<books>,则是文档元素(document element),它是文件中最外面的标签(我们认为元素(element)是起始标签和结束标签之间的内容)。所有其他的标签必须包含在这个标签之内来组成一个有效的XML文件。XML文件的第二行并不一定要包含文档元素;如果有注释或者其他内容,文档元素可以迟些出现。
范例文件中的第三行代码是注释,你会发现它与HTML中使用的注释风格是一样的。这是XML从SGML中继承的语法元素之一。
页面再往下的一些地方,可以发现<desc>标签里有一些特殊的语法。<![CDATA[ ]]>代码用于表示无需进行解析的文本,允许诸如大于号和小于号之类的特殊字符包含在文本中,而无需担心破坏XML的语法。文本必须出现在<![CDATA[和]]>之间才能合适地避免被解析。这样的文本称为Character Data Section,简称CData Section。
下面的一行就是在第二本书的定义之前的:
<?page render multiple authors?>
虽然它看上去很像XML序言,但实际上是一种称为处理指令(processing instruction)的不同类型的语法。处理指令(以下简称PI)的目的是为了给处理页面的程序(例如XML解析器)提供额外的信息。PI通常情况下是没有固定格式的,唯一的要求是紧随第一个问号必须至少有一个字母。在此之后,PI可以包含除了小于号和大于号之外的任何字符串序列。
最常见的PI是用来指定XML文件的样式表:
这个PI一般会直接放在XML序言之后,通常由Web浏览器使用,来将XML数据以特殊的样式显示出来。
历史
XML是从1996年开始有其雏形,并向 W3C(全球信息网联盟)提案,而在1998二月发布为W3C的标准(XML1.0)。 XML的前身是SGML(The Standard Generalized Markup Language),是自IBM从60年代就开始发展的 GML(Generalized Markup Language)标准化后的名称。
GML的重要概念:
文件中能够明确的将标示与内容区隔
所有文件的标签使用方法均一致
1978年,ANSI将GML加以整理规范,发布成为SGML,1986年起为 ISO所采用(ISO 8879),并且被广泛地运用在各种大型的文件计划中,但是SGML是一种非常严谨的文件描述法,导致过于庞大复杂(标准手册就有500多页),难以理解和学习,进而影响其推广与应用。
于是,人们对SGML进行了简化衍生出 HTML。HTML简单,在初期没有任何定义文档外观的相关方法,仅用来在浏览器里显示网页文件。而后,随着因特网的发展,人们为了控制其文件样式,扩充了描述如何显现数据的卷标。在 Netscape与 Microsoft之间的浏览器大战后,HTML标准权威性遭受重大的考验,所幸,到了HTML 4.0时,W3C又恢复了其地位。
同时W3C意识到HTML的原罪:
不能解决所有解释数据的问题-像是影音文件或化学公式、音乐符号等其它型态的内容。
效能问题-需要下载整份文件,才能开始对文件做搜寻的动作。
扩充性、弹性、易读性均不佳。
为了解决以上问题,专家们使用SGML精简制作,并依照HTML的发展经验,产生出一套使用上规则严谨,但是简单的描述数据语言:XML。 XML是在一个这样的背景下诞生的—是不是能有一个更中立的方式,让消费端自行决定要如何消化、呈现从服务端所提供的信息?
而XML目的即在于提供一个对信息能够做精准描述的机制,藉以弥补 HTML太过于表现导向的特质。
[编辑]用途
丰富文件(Rich Documents)-自定文件描述并使其更丰富
属于文件为主的XML技术应用
标记是用来定义一块数据应该如何呈现
解释数据(Metadata)-描述其它文件或在线信息
属于数据为主的XML技术应用
标记是用来说明一块资料的意义
组态档案(Configuration Files)-描述软件的组态参数
二、如何使用xmllib2解析xml字符串
libxml2
xmlReadMemory
xmlParseMemory
网上的大部分关于xml的文章都是处理xml文件的,就没直接处理xml字符串的说明。
下面是用libxml2解析xml格式的字符串的函数顺序:
1. xmlParseMemory,字符串转为XML文档
2. xmlDocGetRootElement,获取XML文档根节点
3. xmlStrcmp,比较XML字符串,与strcmp差不多
4. curr= curr->xmlChildrenNode,XML节点指针指向第一个子节点
5. curr= curr->next,XML节点指针指向下一个兄弟节点
6. xmlNodeGetContent,获取XML节点的内容
7. xmlFreeDoc,释放节点,与free差不多
http://blog.csdn.net/shanzhizi
贴段代码作为参考:
[cpp] view plain copy
#include<iconv.h>
#include<libxml/parser.h>
#include<libxml/xmlmemory.h>
#include"soapH.h"
#include"ExchangeRateWebServiceSoap12.n**ap"
#define FIELD_LEN 16
int conv_charset(const char*dest, const char*src, char*input, size_t ilen, char*output, size_t olen){
iconv_t conv= iconv_open(dest, src);
if( conv==(iconv_t)-1)
return-1;
memset(output, 0, olen);
if( iconv(conv,&input,&ilen,&output,&olen))
return-1;
iconv_close(conv);
return 0;
}
int main(int argc, char**argv){
if( argc!= 2&& argc!= 3){
printf("Usage:%s type [end_point]\n", argv[0]);
printf("\ttype= A: all rate\n");
printf("\ttype= B: basic rate\n");
printf("\ttype= C: cross rate\n");
exit(-1);
}
struct soap soap;
soap_init(&soap);
// don't set is OK
//soap_set_mode(&soap, SOAP_C_UTFSTRING);
struct _ns1__getExchangeRate request;
struct _ns1__getExchangeRateResponse response;
request.theType= argv[1];
char*endpoint= NULL;
if( argc== 3)
endpoint= argv[2];
if( soap_call___ns3__getExchangeRate(&soap, endpoint, NULL,&request,&response)== SOAP_OK){
int len= strlen(response.getExchangeRateResult->__any);
xmlDocPtr pdoc= xmlParseMemory(response.getExchangeRateResult->__any, len);
xmlNodePtr root= xmlDocGetRootElement(pdoc);
xmlNodePtr curr= root;
while( xmlStrcmp(curr->name,(const xmlChar*)"getExchangeRate"))
curr= curr->xmlChildrenNode;
for( curr= curr->xmlChildrenNode; curr; curr= curr->next){
xmlNodePtr data;
for( data= curr->xmlChildrenNode; data; data= data->next){
char ifield[FIELD_LEN];
char ofield[FIELD_LEN];
strcpy(ifield, xmlNodeGetContent(data));
if( conv_charset("GBK","UTF-8", ifield, strlen(ifield), ofield, FIELD_LEN))
printf("%s\t%s\n", data->name, ifield);
else
printf("%s\t%s\n", data->name, ofield);
}
printf("\n");
}
xmlFreeDoc(pdoc);
}
else{
soap_print_fault(&soap, stderr);
}
//<a href="http://blog.csdn.net/shanzhizi">http://blog.csdn.net/shanzhizi</a>
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);
return 0;
}
三、XML解析是什么意思怎么解析啊
XML解析
XML解析是将 XML数据从其序列化字符串格式转换为分层格式的过程。
可以让 DB2®数据库管理器隐式执行解析,也可以显式执行 XML解析。
在下列情况下进行隐式 XML解析:
使用类型为 XML的主变量或使用类型为 XML的参数标记将数据传递至数据库服务器时
数据库服务器在绑定主变量或参数标记的值以便在语句处理期间使用时进行解析
在这种情况下,必须使用隐式解析。
在 INSERT、UPDATE、DELETE或 MERGE语句中将字符串数据类型(character、graphic或 binary)的主变量、参数标记或 SQL表达式指定给 XML列时。当 SQL编译器隐式将 XMLPARSE函数添加至该语句时进行解析。
对输入 XML数据调用 XMLPARSE函数时,执行显式 XML解析。可以在接受 XML数据类型的任何上下文中使用 XMLPARSE的结果。例如,可以将结果指定给 XML列或将它用作类型为 XML的存储过程参数。
XMLPARSE函数采用非 XML、字符或二进制数据类型作为输入。对于嵌入式动态 SQL应用程序,需要将表示 XMLPARSE的输入文档的参数标记强制类型转换为相应的数据类型。例如:
INSERT INTO MyCustomer(Cid, Info)
VALUES(?, xmlparse(document cast(? as clob(1k)) preserve whitespace))
对于静态嵌入式 SQL应用程序,不能将 XMLPARSE函数的主变量自变量声明为 XML类型(XML AS BLOB、XML AS CLOB或 XML AS DBCLOB类型)。
XML解析和空格处理
在隐式或显式 XML解析期间,将数据存储在数据库中时,可以控制是保留还是去掉边界空格字符。
根据 XML标准,空格是文档中用于提高可读性的间隔字符(U+0020)、回车符(U+000D)、换行符(U+000A)或制表符(U+0009)。当任何这些字符作为文本字符串的一部分出现时,不将它们视为空格。
边界空格是出现在元素之间的空格字符。例如,在以下文档中,<a>与<b>以及</b>与</a>之间的空格是边界空格。
<a><b> and between</b></a>
通过显式调用 XMLPARSE,可以使用 STRIP WHITESPACE或 PRESERVE WHITESPACE选项来控制是否保留边界空格。缺省行为是去掉边界空格。
通过隐式 XML解析:
如果输入数据类型不是 XML类型或未强制类型转换为 XML数据类型,则 DB2数据库管理器总是去掉空格。
如果输入数据类型是 XML数据类型,则可以使用 CURRENT IMPLICIT XMLPARSE OPTION专用寄存器来控制是否保留边界空格。可以将此专用寄存器设置为 STRIP WHITESPACE或 PRESERVE WHITESPACE。缺省行为是去掉边界空格。
如果使用 XML验证,则 DB2数据库管理器将忽略 CURRENT IMPLICIT XMLPARSE OPTION专用寄存器,并只使用验证规则来确定下列示例中是去掉还是保留空格:
xmlvalidate(? ACCORDING TO XMLSCHEMA ID schemaname)
xmlvalidate(?)
xmlvalidate(:hvxml ACCORDING TO XMLSCHEMA ID schemaname)
xmlvalidate(:hvxml)
xmlvalidate(cast(? as xml) ACCORDING TO XMLSCHEMA ID schemaname)
xmlvalidate(cast(? as xml))
在这些示例中,?表示 XML数据,而:hvxml是 XML主变量。
有关 XML验证如何影响空格处理方式的信息,请参阅 XML验证。
XML标准指定 xml:space属性,它用于控制是去掉还是保留 XML数据中的空格。xml:space属性覆盖任何空格设置以进行隐式或显式 XML解析。
例如,在以下文档中,无论 XML解析选项如何,总是保留正好在<b>前后的空格,因为这些空格位于具有属性 xml:space="preserve"的节点内:
<a xml:space="preserve"><b><c>c</c>b</b></a>
但是,在以下文档中,可以用 XML解析选项控制正好在<b>前后的空格,因为这些空格位于具有属性 xml:space="default"的节点内:
<a xml:space="default"><b><c>c</c>b</b></a>
XML解析和 DTD
如果输入数据包含内部文档类型声明(DTD)或引用外部 DTD,则 XML解析过程还会检查这些 DTD的语法。此外,解析过程还:
应用内部和外部 DTD定义的缺省值
扩展实体引用和参数实体
示例:文件 c8.xml包含以下文档:
<customerinfo xml:space="preserve" xmlns="http://posample.org" Cid='1008'>
<name>Kathy Smith</name>
<addr country='Canada'>
<street>14 Rosewood</street>
<city>Toronto</city>
<prov-state>Ontario</prov-state>
<pcode-zip>M6W 1E6</pcode-zip>
</addr>
<phone type='work'>416-555-3333</phone>
</customerinfo>
在 JDBC应用程序中,从文件中读取 XML文档,并将数据插入到表 MyCustomer(它是样本 Customer表的副本)的 XML列 Info中。让 DB2数据库服务器执行隐式 XML解析操作。
PreparedStatement insertStmt= null;
String sqls= null;
int cid= 1008;
sqls="INSERT INTO MyCustomer(Cid, Info) VALUES(?,?)";
insertStmt= conn.prepareStatement(sqls);
insertStmt.setInt(1, cid);
File file= new File("c8.xml");
insertStmt.setBinaryStream(2, new FileInputStream(file),(int)file.length());
insertStmt.executeUpdate();
未指定空格处理方式,因此采用缺省行为:去掉空格。但是,文档包含 xml:space="preserve"属性,因此保留空格。这表示将保留文档中元素之间的回车符、换行符和空格。
如果检索存储的数据,则内容看起来如下所示:
<customerinfo xml:space="preserve" xmlns="http://posample.org" Cid='1008'>
<name>Kathy Smith</name>
<addr country='Canada'>
<street>14 Rosewood</street>
<city>Toronto</city>
<prov-state>Ontario</prov-state>
<pcode-zip>M6W 1E6</pcode-zip>
</addr>
<phone type='work'>416-555-3333</phone>
</customerinfo>
示例:假定以下文档位于 BLOB主变量 blob_hostvar中。
<customerinfo xml:space="default" xmlns="http://posample.org" Cid='1009'>
<name>Kathy Smith</name>
<addr country='Canada'>
<street>15 Rosewood</street>
<city>Toronto</city>
<prov-state>Ontario</prov-state>
<pcode-zip>M6W 1E6</pcode-zip>
</addr>
<phone type='work'>416-555-4444</phone>
</customerinfo>
在静态嵌入式 C应用程序中,将主变量中的文档插入到表 MyCustomer的 XML列 Info中。该主变量不是 XML类型,因此需要显式执行 XMLPARSE。指定 STRIP WHITESPACE以除去任何边界空格。
EXEC SQL BEGIN DECLARE SECTION;
SQL TYPE BLOB(10K) blob_hostvar;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL INSERT INTO MyCustomer(Cid, Info)
VALUES(1009,
XMLPARSE(DOCUMENT:blob_hostvar STRIP WHITESPACE));
文档包含 xml:space="default"属性,因此指定了 STRIP WHITESPACE的 XMLPARSE将控制空格处理方式。这表示将除去文档中元素之间的回车符、换行符和空格。
如果检索存储的数据,则您将看到具有以下内容的单个行:
<customerinfo xml:space="default" xmlns="http://posample.org" Cid='1009'>
<name>Kathy Smith</name><addr country='Canada'><street>15 Rosewood</street>
<city>Toronto</city><prov-state>Ontario</prov-state><pcode-zip>M6W 1E6</pcode-zip>
</addr><phone type='work'>416-555-4444</phone></customerinfo>
示例:在 C语言应用程序中,主变量 clob_hostvar包含以下文档,该文档包含内部 DTD:
<!DOCTYPE prod [<!ELEMENT description(name,details,price,weight)>
<!ELEMENT name(#PCDATA)>
<!ELEMENT details(#PCDATA)>
<!ELEMENT price(#PCDATA)>
<!ELEMENT weight(#PCDATA)>
<!ENTITY desc"Anvil">
]>
<product xmlns="http://posample.org" pid=''110-100-01''>
<description>
<name>&desc;</name>
<details>Very heavy</details>
<price> 9.99</price>
<weight>1 kg</weight>
</description>
</product>'
将数据插入到表 MyProduct中,它是样本 Product表的副本:
EXEC SQL BEGIN DECLARE SECTION;
SQL TYPE CLOB(10K) clob_hostvar;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL insert into
Product( pid, name, Price, PromoPrice, PromoStart, PromoEnd, description)
values('110-100-01','Anvil', 9.99, 7.99,'11-02-2004','12-02-2004',
XMLPARSE( DOCUMENT:clob_hostvar STRIP WHITESPACE));
XMLPARSE指定去掉空格,因此将除去文档内的边界空格。此外,在数据库服务器执行 XMLPARSE时,它将实体引用&desc;替换为它的值。
如果检索存储的数据,则您将看到具有以下内容的单个行:
<product xmlns="http://posample.org" pid="110-100-01"><description><name>Anvil
</name><details>Very heavy</details><price> 9.99</price>
<weight>1 kg</weight></description></product>
文章分享到这里,希望我们关于XML 解析_xml解析和如何使用xmllib2解析xml字符串的内容能够给您带来一些新的认识和思考。如果您还有其他问题,欢迎继续探索我们的网站或者与我们交流,我们将尽力为您提供满意的答案。