xml操作C++表述

xml操作C++表述
xml操作C++表述

VC中tinyxml使用方法简介

1.加载文件。

TiXmlDocument doc( "demo.xml" );

doc.LoadFile();

2.

void main(void)

{

TiXmlDocument doc("example1.xml");

bool loadOkay = doc.LoadFile();

if (loadOkay)

{

printf("\n%s:\n", pFilename);

dump_to_stdout( &doc ); // defined later in the tutorial

}

else

{

printf("Failed to load file \"%s\"\n", pFilename);

}

return;

}

example1.xml 的内容如果是:

World

输出为:

DOCUMENT

+ DECLARATION

+ ELEMENT Hello

+ TEXT[World]

3.建立文档的方法.

void build( )

{ TiXmlDocument doc;

TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" ); TiXmlElement * element = new TiXmlElement( "Hello" ); TiXmlText * text = new TiXmlText( "World" );

element->LinkEndChild( text );

doc.LinkEndChild( decl );

doc.LinkEndChild( element );

doc.SaveFile( "example1.xml" );

}

4.设定节点属性。

TiXmlElement window = new TiXmlElement( "Demo" ); window->SetAttribute("name", "Circle");

window->SetAttribute("x", 5);

window->SetAttribute("y", 15);

window->SetDoubleAttribute("radius", 3.14159);

5.获取元素的所有属性,并打印出属性名称和值

int printElement(TiXmlElement* pElement, unsigned int indent)

{

if ( !pElement ) return 0;

TiXmlAttribute* pAttrib=pElement->FirstAttribute();

int i=0;

int ival;

double dval;

const char* pIndent=getIndent(indent);

printf("\n");

while (pAttrib)

{

printf( "%s%s: value=[%s]", pIndent, pAttrib->Name(), pAttrib->Value());

if (pAttrib->QueryIntValue(&ival)==TIXML_SUCCESS) printf( " int=%d", ival);

if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval); printf( "\n" );

i++;

pAttrib=pAttrib->Next();

}

return i;

}

6.写入文件,其实上面已经用到了。

doc.SaveFile( saveFilename );

7.建立一个其内容如下的文档:

Welcome to MyApp

Thank you for using MyApp

void main( )

{

TiXmlDocument doc;

TiXmlElement* msg;

TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" ); //文档声明doc.LinkEndChild( decl );

TiXmlElement * root = new TiXmlElement( "MyApp" );

doc.LinkEndChild( root ); //根元素

TiXmlComment * comment = new TiXmlComment();//xml注释comment->SetValue(" Settings for MyApp " );

root->LinkEndChild( comment ); //插入根元素之间

TiXmlElement * msgs = new TiXmlElement( "Messages" );

root->LinkEndChild( msgs ); //定义元素Messages,插入到root

msg = new TiXmlElement( "Welcome" ); //定义新元素,并插入到msgs msg->LinkEndChild( new TiXmlText( "Welcome to MyApp" ));

msgs->LinkEndChild( msg );

msg = new TiXmlElement( "Farewell" ); //定义新元素,并插入到msgs msg->LinkEndChild( new TiXmlText( "Thank you for using MyApp" )); msgs->LinkEndChild( msg );

TiXmlElement * windows = new TiXmlElement( "Windows" );

root->LinkEndChild( windows ); //root中插入新元素windows

TiXmlElement * window;

window = new TiXmlElement( "Window" );

windows->LinkEndChild( window ); //定义新元素,并设定其属性。window->SetAttribute("name", "MainFrame");

window->SetAttribute("x", 5);

window->SetAttribute("y", 15);

window->SetAttribute("w", 400);

window->SetAttribute("h", 250);

TiXmlElement * cxn = new TiXmlElement( "Connection" );

root->LinkEndChild( cxn );

cxn->SetAttribute("ip", "192.168.0.1");

cxn->SetDoubleAttribute("timeout", 123.456); // floating point attrib

dump_to_stdout( &doc );

doc.SaveFile( "appsettings.xml" ); //保存文件

}

8.对象到XML的转换。

///class

#include

#include

using namespace std;

typedef std::map MessageMap;

// a basic window abstraction - demo purposes only

class WindowSettings

{

public:

int x,y,w,h;

string name;

WindowSettings()

: x(0), y(0), w(100), h(100), name("Untitled")

{

}

WindowSettings(int x, int y, int w, int h, const string& name) {

this->x=x;

this->y=y;

this->w=w;

this->h=h;

this->name=name;

}

};

class ConnectionSettings

{

public:

string ip;

double timeout;

};

class AppSettings

{

public:

string m_name;

MessageMap m_messages;

list m_windows; ConnectionSettings m_connection;

AppSettings() {}

void save(const char* pFilename);

void load(const char* pFilename);

// just to show how to do it

void setDemoValues()

{

m_name="MyApp";

m_messages.clear();

m_messages["Welcome"]="Welcome to "+m_name;

m_messages["Farewell"]="Thank you for using "+m_name;

m_windows.clear();

m_windows.push_back(WindowSettings(15,15,400,250,"Main"));

m_connection.ip="Unknown";

m_connection.timeout=123.456;

}

};

///创建文件,并加载

int main(void)

{

AppSettings settings;

settings.save("appsettings2.xml");

settings.load("appsettings2.xml");

return 0;

}

///创建,修改和保存

int main(void)

{

// block: customise and save settings

{

AppSettings settings;

settings.m_name="HitchHikerApp";

settings.m_messages["Welcome"]="Don't Panic";

settings.m_messages["Farewell"]="Thanks for all the fish";

settings.m_windows.push_back(WindowSettings(15,25,300,250,"BookFrame")); settings.m_connection.ip="192.168.0.77";

settings.m_connection.timeout=42.0;

settings.save("appsettings2.xml");

}

// block: load settings

{

AppSettings settings;

settings.load("appsettings2.xml");

printf("%s: %s\n", settings.m_name.c_str(),

settings.m_messages["Welcome"].c_str());

WindowSettings & w=settings.m_windows.front();

printf("%s: Show window '%s' at %d,%d (%d x %d)\n",

settings.m_name.c_str(), https://www.360docs.net/doc/9d9845232.html,.c_str(), w.x, w.y, w.w, w.h);

printf("%s: %s\n", settings.m_name.c_str(), settings.m_messages["Farewell"].c_str()); }

return 0;

}

输出:

HitchHikerApp: Don't Panic

HitchHikerApp: Show window 'BookFrame' at 15,25 (300 x 100)

HitchHikerApp: Thanks for all the fish

9.XML到对象的转换。

void AppSettings::load(const char* pFilename)

{

TiXmlDocument doc(pFilename);

if (!doc.LoadFile()) return;

TiXmlHandle hDoc(&doc);

TiXmlElement* pElem;

TiXmlHandle hRoot(0);

// block: name

{

pElem=hDoc.FirstChildElement().Element();

// should always have a valid root but handle gracefully if it does

if (!pElem) return;

m_name=pElem->Value();

// save this for later

hRoot=TiXmlHandle(pElem);

}

// block: string table

{

m_messages.clear(); // trash existing table

pElem=hRoot.FirstChild( "Messages" ).FirstChild().Element();

for( pElem; pElem; pElem=pElem->NextSiblingElement())

{

const char *pKey=pElem->Value();

const char *pText=pElem->GetText();

if (pKey && pText)

{

m_messages[pKey]=pText;

}

}

}

// block: windows

{

m_windows.clear(); // trash existing list

TiXmlElement* pWindowNode=hRoot.FirstChild( "Windows" ).FirstChild().Element();

for( pWindowNode; pWindowNode; pWindowNode=pWindowNode->NextSiblingElement()) {

WindowSettings w;

const char *pName=pWindowNode->Attribute("name");

if (pName) https://www.360docs.net/doc/9d9845232.html,=pName;

pWindowNode->QueryIntAttribute("x", &w.x); // If this fails, original value is left

as-is

pWindowNode->QueryIntAttribute("y", &w.y);

pWindowNode->QueryIntAttribute("w", &w.w);

pWindowNode->QueryIntAttribute("hh", &w.h);

m_windows.push_back(w);

}

}

// block: connection

{

pElem=hRoot.FirstChild("Connection").Element();

if (pElem)

{

m_connection.ip=pElem->Attribute("ip");

pElem->QueryDoubleAttribute("timeout",&m_connection.timeout);

}

}

}

10.一个比较完整的例子,加载任意的XML文档,并在控制台上输出。

//

#include "stdafx.h"

#include "tinyxml.h"

// ----------------------------------------------------------------------

// STDOUT dump and indenting utility functions

// ----------------------------------------------------------------------

const unsigned int NUM_INDENTS_PER_SPACE=2;

const char * getIndent( unsigned int numIndents )

{

static const char * pINDENT=" + ";

static const unsigned int LENGTH=strlen( pINDENT );

unsigned int n=numIndents*NUM_INDENTS_PER_SPACE;

if ( n > LENGTH ) n = LENGTH;

return &pINDENT[ LENGTH-n ];

}

// same as getIndent but no "+" at the end

const char * getIndentAlt( unsigned int numIndents )

{

static const char * pINDENT=" ";

static const unsigned int LENGTH=strlen( pINDENT );

unsigned int n=numIndents*NUM_INDENTS_PER_SPACE;

if ( n > LENGTH ) n = LENGTH;

return &pINDENT[ LENGTH-n ];

}

int dump_attribs_to_stdout(TiXmlElement* pElement, unsigned int indent)

{

if ( !pElement ) return 0;

TiXmlAttribute* pAttrib=pElement->FirstAttribute();

int i=0;

int ival;

double dval;

const char* pIndent=getIndent(indent);

printf("\n");

while (pAttrib)

{

printf( "%s%s: value=[%s]", pIndent, pAttrib->Name(), pAttrib->Value());

if (pAttrib->QueryIntValue(&ival)==TIXML_SUCCESS) printf( " int=%d", ival);

if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval); printf( "\n" );

pAttrib=pAttrib->Next();

}

return i;

}

void dump_to_stdout( TiXmlNode* pParent, unsigned int indent = 0 ) {

if ( !pParent ) return;

TiXmlNode* pChild;

TiXmlText* pText;

int t = pParent->Type();

printf( "%s", getIndent(indent));

int num;

switch ( t )

{

case TiXmlNode::DOCUMENT:

printf( "Document" );

break;

case TiXmlNode::ELEMENT:

printf( "Element [%s]", pParent->Value() );

num=dump_attribs_to_stdout(pParent->ToElement(), indent+1); switch(num)

{

case 0: printf( " (No attributes)"); break;

case 1: printf( "%s1 attribute", getIndentAlt(indent)); break; default: printf( "%s%d attributes", getIndentAlt(indent), num); break; }

break;

case TiXmlNode::COMMENT:

printf( "Comment: [%s]", pParent->Value());

break;

case TiXmlNode::UNKNOWN:

printf( "Unknown" );

break;

case TiXmlNode::TEXT:

pText = pParent->ToText();

printf( "Text: [%s]", pText->Value() );

case TiXmlNode::DECLARATION:

printf( "Declaration" );

break;

default:

break;

}

printf( "\n" );

for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {

dump_to_stdout( pChild, indent+1 );

}

}

// load the named file and dump its structure to STDOUT

void dump_to_stdout(const char* pFilename)

{

TiXmlDocument doc(pFilename);

bool loadOkay = doc.LoadFile();

if (loadOkay)

{

printf("\n%s:\n", pFilename);

dump_to_stdout( &doc ); // defined later in the tutorial

}

else

{

printf("Failed to load file \"%s\"\n", pFilename);

}

}

// ----------------------------------------------------------------------

// main() for printing files named on the command line

// ----------------------------------------------------------------------

int main(int argc, char* argv[])

{

for (int i=1; i

{

dump_to_stdout(argv[i]);

}

return 0;

}

tinyxml使用笔记与总结

在TinyXML中,根据XML的各种元素来定义了一些类:

TiXmlBase:整个TinyXML模型的基类。

TiXmlAttribute:对应于XML中的元素的属性。

TiXmlNode:对应于DOM结构中的节点。

TiXmlComment:对应于XML中的注释。

TiXmlDeclaration:对应于XML中的申明部分,即<?versiong="1.0" ?>。 TiXmlDocument:对应于XML的整个文档。

TiXmlElement:对应于XML的元素。

TiXmlText:对应于XML的文字部分。

TiXmlUnknown:对应于XML的未知部分。

TiXmlHandler:定义了针对XML的一些操作。

例如:

Go to the Toy store!

Do bills

整个对象树:

TiXmlDocument "demo.xml"

TiXmlDeclaration "version=’1.0′" "standalone=no"

TiXmlComment " Our to do list data"

TiXmlElement "ToDo"

TiXmlElement "Item" Attribtutes: priority = 1

TiXmlText "Go to the "

TiXmlElement "bold"

TiXmlText "Toy store!"

TiXmlElement "Item" Attributes: priority=2

TiXmlText "Do bills"

在tinyXML中,用FirstChild("名字")查找节点时,调用FirstChild函数的节点与要查找的节点必须成“父子关系”。

句柄

想要健壮地读取一个XML文档,检查方法调用后的返回值是否为null是很重要的。一种安全的检错实现可能会产生像这样的代码:

TiXmlElement* root = document.FirstChildElement( "Document" );

if ( root )

{

TiXmlElement* element = root->FirstChildElement( "Element" );

if ( element )

{

TiXmlElement* child = element->FirstChildElement( "Child" );

if ( child )

{

TiXmlElement* child2 = child->NextSiblingElement( "Child" );

if ( child2 )

{

// Finally do something useful.

用句柄的话就不会这么冗长了,使用TiXmlHandle类,前面的代码就会变成这样:

TiXmlHandle docHandle( &document );

TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Ele ment" ).Child( "Child", 1 ).ToElement();

if ( child2 )

{

// do something useful

一、读取XML,设置节点文本

如下XML片段:

8

69

1

1

/mnt/share/1.bmp

0

/mnt/share/2.bmp

2

1

0

.

要设置BROADCAST_VERSION节点的值 8为其他值,可参考如下代码(将值加1):

用ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )方法替换

TiXmlDocument doc("zapp.conf");

doc.LoadFile();

TiXmlHandle docHandle( &doc );

TiXmlElement* Broadcast_ver = docHandle.FirstChild("ZXML").FirstChild("ZAP P").FirstChild("VBS_RUNTIME_PARAMS").FirstChildElement("BROADCAST_VERSION"). ToElement();

TiXmlNode * oldnode = Broadcast_ver->FirstChild();

const char *ver = Broadcast_ver->GetText();

int oldVer = atoi(ver);

CString newVer;

newVer.Format("%d",oldVer+1);

TiXmlText newText(newVer);

Broadcast_ver->ReplaceChild(oldnode,newText);

AfxMessageBox(Broadcast_ver->GetText());//输出值

doc.SaveFile();

二,删除节点,属性值

RemoveChild( TiXmlNode* removeThis )方法删除父节点的子节点,

RemoveAttribute( const char * name )方法删除属性值.

例如删除BROADCAST_VERSION节点

TiXmlHandle docHandle( &doc );

TiXmlElement* Broadcast_ver = docHandle.FirstChild("ZXML").FirstChild ("ZAPP").FirstChild("VBS_RUNTIME_PARAMS").ToElement();

TiXmlNode * node = Broadcast_ver->FirstChild("BROADCAST_VERSION");

Broadcast_ver->RemoveChild(node);

也可以删除整个SOURCE_1节点:

TiXmlHandle docHandle( &doc );

TiXmlElement* Broadcast = docHandle.FirstChild("ZXML").FirstChild("ZAP P").FirstChild("VBS_RUNTIME_PARAMS").FirstChild("Broadcast").ToElement();

TiXmlNode * node = Broadcast->FirstChild("SOURCE_1");

Broadcast->RemoveChild(node);

删除BROADCAST_VERSION的info属性:

TiXmlHandle docHandle( &doc );

TiXmlElement* Broadcast_ver = docHandle.FirstChild("ZXML").FirstChild ("ZAPP").FirstChild("VBS_RUNTIME_PARAMS").FirstChildElement("BROADCAST_VERS ION").ToElement();

Broadcast_ver->RemoveAttribute("info"); //删除info

可以借助NextSiblingElement()方法实现递归删除.

三,添加节点,属性值

例如在SOURCE_3下添加BROADCAST_PID节点:

TiXmlHandle docHandle( &doc );

TiXmlElement* Broadcast = docHandle.FirstChild("ZXML").FirstChild("ZAP P").FirstChild("VBS_RUNTIME_PARAMS").FirstChild("Broadcast").ToElement();

TiXmlElement* Broadcast_Pid = new TiXmlElement("BROADCAST_PID");

TiXmlText *text =new TiXmlText("7215");

Broadcast_Pid->SetAttribute("info","the pid");

Broadcast_Pid->LinkEndChild(text);

Broadcast->LinkEndChild(Broadcast_Pid);

将在SOURCE_3后添加新的节点:

7215

四,最后说一下中文乱码的问题

乱码是由于GB2312与UTF8之间转换不当造成的,tinyxml在处理UTF8本身没有问题,当你打开一个UTF8的文档,可以在加载的时候指定UTF8的方式,或者文档声明处指明的编码格式,tinyxml 会按照相应的编码格式加载,但很多时候当我们输出或写入中文字段时会出现乱码,无论在内存,

还是打印出来的内容.这是因为我们的软件通常是GB2312编码,而读取或写入的内容是UTF8,自

然就会出错.可以借助网上的两个函数来实现转换(原作者不详):

void ConvertUtf8ToGBK(CString& strUtf8)

{

int len=MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUtf8, -1, NULL, 0);

unsigned short * wszGBK = new unsigned short[len+1];

memset(wszGBK, 0, len * 2 + 2);

MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUtf8, -1, wszGBK, len);

len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NU LL);

char *szGBK=new char[len + 1];

memset(szGBK, 0, len + 1);

WideCharToMultiByte (CP_ACP, 0, wszGBK, -1, szGBK, len, NULL,NULL);

strUtf8 = szGBK;

delete[] szGBK;

delete[] wszGBK;

}

void ConvertGBKToUtf8(CString& strGBK)

{

int len=MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strGBK, -1, NULL, 0);

unsigned short * wszUtf8 = new unsigned short[len+1];

memset(wszUtf8, 0, len * 2 + 2);

MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strGBK, -1, wszUtf8, len);

len = WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1, NULL, 0, NUL L, NULL);

char *szUtf8=new char[len + 1];

memset(szUtf8, 0, len + 1);

WideCharToMultiByte (CP_UTF8, 0, wszUtf8, -1, szUtf8, len, NULL,NU LL);

strGBK = szUtf8;

delete[] szUtf8;

delete[] wszUtf8;

}

当然,你也可以用MultiByteToWideChar,WideCharToMultiByte函数自己实现转换.以上是简单应用的几个举例,理解他们,相信你已经能写出满足自己需要的代码了.

XML DOM 删除节点

实例

在下面的例子中,我们将使用XML文件books.xml,以及JavaScript函数loadXMLDoc()。

删除元素

本例使用removeChild()从载入的XML中删除最后一个< book>元素。

从文本节点删除文本

本例使用deleteData()从已载入的XML中的一个文本节点删除文本。

删除属性

本例使用removeAttribute()从已载入的XML中删除所有的"category"属性。

使用removeAttributeNode()

本例使用removeAttributeNode()从已载入的XML中删除所有的"category"属性。

删除某个元素

removeChild()可被用来删除某个指定的节点。

下面的代码片段会从已载入的XML中删除最后一个< book>元素:

//check if last child node is an element node

function get_lastchild(n)

{

var x=https://www.360docs.net/doc/9d9845232.html,stChild;

while (x.nodeType!=1)

{

x=x.previousSibling;

}

return x;

}

xmlDoc=loadXMLDoc("books.xml");

var x=xmlDoc.documentElement;

x.removeChild(get_lastchild(x));

注释:Internet Explorer会忽略节点之间产生的空白文本节点(例如换行字符),而Mozilla不会这样。因此,在上面的例子中,get_lastchild()函数会检查参数的最后一个子节点的节点类型。

元素节点的节点类型是1,因此假如参数中节点的最末子节点不是元素节点,那么它就会移至上一个节点,并检查此节点是否为元素节点。这个过程会持续到最后一个子节点被找到为止。通过这个办法,我们就可以在Internet Explorer 和Mozilla中得到正确的结果了。

从元素删除文本

deleteData()方法被用来从文本节点删除数据。

deleteData()方法有两个参数:

?offset - 从何处开始删除字符。偏移量的起始值是0

?count - 删除多少字符

下面的代码片段会从已载入的XML中的首个< title>元素删除开头的九个字符:

xmlDoc=loadXMLDoc("books.xml");

var x=xmlDoc.getElementsByTagName("title")[0].childNodes[0];

x.deleteData(0,9);

删除属性

removeAttribute()方法被用来删除属性节点。

下面的代码片段会删除每个< book>元素中所有的"category"属性:

xmlDoc=loadXMLDoc("books.xml");

var x=xmlDoc.getElementsByTagName('book');

for(i=0;i< x.length;i++)

{

x.item(i).removeAttribute('category');

}

removeAttributeNode()

removeAttributeNode()方法被用来删除某个属性节点。

下面的代码片段会删除每个< book>元素中所有的"category"属性:

xmlDoc=loadXMLDoc("books.xml");

var x=xmlDoc.getElementsByTagName('book');

for(i=0;i< x.length;i++)

{

attnode=x.item(i).getAttributeNode("category")

old_att=x.item(i).removeAttributeNode(attnode);

document.write("Removed attribute: " + old_https://www.360docs.net/doc/9d9845232.html, + "< br />"); }

输出:

Removed attribute: category

Removed attribute: category

Removed attribute: category

Removed attribute: category

XML DOM 添加节点

实例

在下面的例子中,我们将使用XML文件books.xml,以及JavaScript函数loadXMLDoc()。

向一个节点列表的末尾添加一个节点

本例使用createElement()来创建一个新的元素,并使用appendChild()将此节点添加到一个节点列表。

在特定的节点之前添加节点

本例使用createElement()来创建一个新的元素,并使用insertBefore()将此节点插入到特定的节点之前

java_Dom4j解析XML详解

学习:Dom4j 1、DOM4J简介 DOM4J是https://www.360docs.net/doc/9d9845232.html, 出品的一个开源XML 解析包。DOM4J应用于Java 平台,采用了Java 集合框架并完全支持DOM,SAX 和JAXP。 DOM4J 使用起来非常简单。只要你了解基本的XML-DOM 模型,就能使用。 Dom:把整个文档作为一个对象。 DOM4J 最大的特色是使用大量的接口。它的主要接口都在org.dom4j里面定义:

接口之间的继承关系如下: interface https://www.360docs.net/doc/9d9845232.html,ng.Cloneable interface org.dom4j.Node interface org.dom4j.Attribute interface org.dom4j.Branch interface org.dom4j.Document interface org.dom4j.Element interface org.dom4j.CharacterData interface org.dom4j.CDATA interface https://www.360docs.net/doc/9d9845232.html,ment interface org.dom4j.Text interface org.dom4j.DocumentType interface org.dom4j.Entity interface org.dom4j.ProcessingInstruction 2、XML文档操作1 2.1、读取XML文档: 读写XML文档主要依赖于org.dom4j.io包,有DOMReader和SAXReader两种方式。因为利用了相同的接口,它们的调用方式是一样的。 public static Docum ent load(String filenam e) { Document docum ent =null; try { SAXReader saxReader = new SAXReader(); docum ent =saxReader.read(new File(filename)); //读取XML文件,获得docum ent 对象 } catch (Exception ex) { ex.printStackTrace();

C++文件操作详解(ifstream、ofstream、fstream)

C++文件操作详解(ifstream 、ofstream 、fstream ) C++通过以下几个类支持文件的输入输岀: ofstream: 写操作(输岀)的文件类 ifstream: 读操作(输入)的文件类 fstream: 可同时读写操作的文件类 打开 文件(Open a file ) 对这些类的一个对象所做的第一个操作通常就是将它和一个真正的文件联系起来, 也就是说打开 一个文件。被打开的文件在程序中由一个流对象 (stream object )来表示(这些类的一个实例), 而对这个流对象所做的任何输入输岀操作实际就是对该文件所做的操作。 要通过一个流对象打开一个文件,我们使用它的成员函数 open (): void ope n (const char * file name, ope nm ode mode ); 这里file name 是一个字符串,代表要打开的文件名, mode 是以下标志符的一个组合: ios::i n 为输入(读)而打开文件 ios::out 为输岀(写)而打开文件 ios::ate 初始位置:文件尾 ios::app 所有输岀附加在文件末尾 ios::tru nc 如果文件已存在则先删除该文件 ios::b inary 二进制方式 这些标识符可以被组合使用,中间以 ”或”操作符(|)间隔。例如,如果我们想要以二进制方式打 开文件"example.bin" 来写入一些数据,我们可以通过以下方式调用成员函数 open ()来实现: ofstream file; file.ope n ("example.b in ”,ios::out | ios::app | ios::b in ary ); ofstream, ifstream 和fstream 所有这些类的成员函数 ope n 都包含了一个默认打开文件的方 式,这三个类的默认方式各不相同: 类 参数的默认方式 ofstream i os::out | ios::trunc ifstream i os::in fstream ios::i n | ios::out 只有当函数被调用时没有声明方式参数的情况下, 默认值才会被采用。 如果函数被调用时声明了 任何参数,默认值将被完全改写,而不会与调用参数组合。 由于对类ofstream, ifstream 和fstream 的对象所进行的第一个操作通常都是打开文件,这 些类都有一个构造函数可以直接调用 open 函数,并拥有同样的参数。这样,我们就可以通过以 下方式进行与上面同样的定义对象和打开文件的操作: (由ostream 引申而来) (由istream 引申而来) (由iostream 引申而来)

Python解析XML的三种方式

一、什么是 XML? XML 被设计用来传输和存储数据。它也是元标记语言,即定义了用于定义其他与特定领域有关的、语义的、结构化的标记语言的句法语言。 准备一个解析用的xml如下: 1 laoz 老曾 30 https://www.360docs.net/doc/9d9845232.html, 我是老曾 2 qz 强子 30 https://www.360docs.net/doc/9d9845232.html, 我是强子 1、第一行是 XML 声明 它定义 XML 的版本(1.0)和所使用的编码(utf-8 : 万国码, 可显示各种语言) 2、必须包含根元素(有且只有一个) 该元素是所有其他元素的父元素,这里的根元素是Data ..

所有的都被包含在里面 3、元素开始标签必须要有结束标签 < account > 元素有 6个子元素:、< description > 每个元素都有对应的关闭标签(跟HTML不一样,有一些是不需要关闭的,比如,
) 4、XML 标签对大小写敏感 比如是不一样的 5、XML 属性值必须加引号 < account name=laoz>这样会报错的,必须"laoz"才行 二、Python 对 XML 的解析 Python 有三种方法解析 XML,SAX,DOM,以及 ElementTree。 DOM会把整个XML读入内存,解析为树,因此占用内存大,解析慢,优点是可以任意遍历树的节点。SAX是流模式,边读边解析,占用内存小,解析快,缺点是我们需要自己处理事件。 1、利用DOM解析XML 一个 DOM 的解析器在解析一个 XML 文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后你可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件。

堡垒主机用户操作手册运维管理

堡垒主机用户操作手册 运维管理 版本2.3.2 2011-06 目录1.前言...................................................... 1.1.系统简介 .............................................. 1.2.文档目的 .............................................. 1.3.读者对象 .............................................. 2.登录系统.................................................. 2.1.静态口令认证登录 (3) 2.2.字证书认证登录 ........................................ 2.3.动态口令认证登录 ...................................... 2.4.LDAP域认证登录........................................ 2.5.单点登录工具 ..........................................

3.单点登录(SS0)........................................... 3.1.安装控件 .............................................. 3.2.单点登录工具支持列表 .................................. 3.3.单点登录授权资源查询 .................................. 3.4.单点登录操作 .......................................... Windows资源类(域内主机\域控制器 \windows2003\2008) Unix\Linux资源类............................... 数据库(独立)资源类 ........................... ORACLE_PLSQL单点登录........................... ORACLE_SQLDeveleper单点登录.................... MSSQLServer2000查询分析器单点登录.............. MSSQLServer2000企业管理器单点登录.............. SQLServer2005ManagementStudio单点登录.......... SQLServer2008ManagementStudio单点登录.......... SybaseDbisqlg单点登录..........................

XML报文解析测试

XML报文解析测试 在平时工作中,难免会遇到把 XML 作为数据存储格式。面对目前种类繁多的解决方案,哪个最适合我们呢?在这篇文章中,我对这四种主流方案做一个不完全评测,仅仅针对遍历 XML 这块来测试,因为遍历 XML 是工作中使用最多的(至少我认为)。 预备 测试环境: AMD 毒龙1.4G OC 1.5G、256M DDR333、Windows2000 Server SP4、Sun JDK 1.4.1+Eclipse 2.1+Resin 2.1.8,在 Debug 模式下测试。 XML 文件格式如下: <?xml version="1.0" encoding="GB2312"?> <RESULT> <VALUE> <NO>A1234</NO> <ADDR>四川省XX县XX镇XX路X段XX号</ADDR> </VALUE> <VALUE> <NO>B1234</NO> <ADDR>四川省XX市XX乡XX村XX组</ADDR> </VALUE> </RESULT> 测试方法: 采用 JSP 端调用Bean(至于为什么采用JSP来调用,请参考: https://www.360docs.net/doc/9d9845232.html,/rosen/archive/2004/10/15/138324.aspx),让每一种方案分别解析10K、100K、1000K、10000K的 XML 文件,计算其消耗时间(单位:毫秒)。 JSP 文件: <%@ page contentType="text/html; charset=gb2312" %> <%@ page import="com.test.*"%> <html> <body> <% String args[]={""}; MyXMLReader.main(args); %>

C++文件操作详细解

C++文件操作详解(ifstream、ofstream、fstream)C++ 通过以下几个类支持文件的输入输出:

你可以通过调用成员函数is_open()来检查一个文件是否已经被顺利的打开了: bool is_open(); 它返回一个布尔(bool)值,为真(true)代表文件已经被顺利打开,假( false )则相反。 关闭文件(Closing a file) 当文件读写操作完成之后,我们必须将文件关闭以使文件重新变为可访问的。关闭文件需要调用成员函数close(),它负责将缓存中的数据排放出来并关闭文件。它的格式很简单: void close (); 这个函数一旦被调用,原先的流对象(stream object)就可以被用来打开其它的文件了,这个文件也就可以重新被其它的进程(process)所有访问了。 为防止流对象被销毁时还联系着打开的文件,析构函数(destructor)将会自动调用关闭函数close。 文本文件(Text mode files)

类ofstream, ifstream 和fstream 是分别从ostream, istream 和iostream 中引申而来的。这就是为什么 fstream 的对象可以使用其父类的成员来访问数据。 一般来说,我们将使用这些类与同控制台(console)交互同样的成员函数(cin 和 cout)来进行输入输出。如下面的例题所示,我们使用重载的插入操作符<<: // writing on a text file #include int main () { ofstream examplefile ("example.txt"); if (examplefile.is_open()) { examplefile << "This is a line.\n"; examplefile << "This is another line.\n"; examplefile.close(); } return 0; file example.txt This is a line. This is another line.

VC++ xml解析

三种最流行的开放源码XML 库是expat、libxml 和Xerces。 第一部分:DOM解析: 概述:DOM解析将会把一个完整的XML文档读进来,生成一个结构树。这样会要把XML文档全部都加载到内在中。所以解析起来的速度会要慢一些。 1、如何加载xml文件: //创建DOM,加载XML文档 MSXML::IXMLDOMDocumentPtr pCommandDoc; pCommandDoc.CreateInstance(__uuidof(MSXML::DOMDocument)); pCommandDoc->put_async(V ARIANT_FALSE); pCommandDoc->put_validateOnParse(VARIANT_FALSE); pCommandDoc->put_resolveExternals(V ARIANT_FALSE); pCommandDoc->put_preserveWhiteSpace(V ARIANT_TRUE); pCommandDoc->load(file.GetBuffer(0)); 2、在XML文档中查找指定的结点: //找到 MSXML::IXMLDOMNodePtr pRootNode=pCommandDoc->selectSingleNode("root/record"); if (pRootNode==NULL) { return ; } 3、得到XML文档中,结点的属性 CString strTemp; MSXML::IXMLDOMNamedNodeMapPtr pAttrs = NULL; pRootNode->get_attributes(&pAttrs); if (pAttrs==NULL) { return; } MSXML::IXMLDOMNodePtr pRequestTypeAttr=pAttrs->getQualifiedItem("name",""); _bstr_t strRequestType=pRequestTypeAttr->Gettext(); strTemp=strRequestType.operator char *(); 4、得到结点的内容 _bstr_t strVisiPort=pNode->Gettext(); 5、设置结点的内容 HRESULT hr=pNode->put_text(_bstr_t(m_strGatewayPassword)); 6、设置一个属性内容 IXMLDOMAttribute *pa=NULL; bstr = SysAllocString(L"属性1"); pXMLDom->createAttribute(bstr,&pNode); var = VariantString(L"strin"); pa->put_value(var); pRoot->setAttributeNode(pa, &pa1); 第二部分、如何使用SAX解析

C#中的文件读写操作详解

C#中的文件读写操作详解(摘自互动维客:https://www.360docs.net/doc/9d9845232.html,,更多内容 请访问互动维客!) C#中的文件操作详解 微软的.Net框架为我们提供了基于流的I/O操作方式,这样就大大简化了开发者的工作。因为我们可以对一系列的通用对象进行操作,而不必关心该I/O操作是和本机的文件有关还是和网络中的数据有关。.Net框架主要为我们提供了一个System.IO命名空间,该命名空间基本包含了所有和I/O操作相关的类。 本文将向大家介绍一些基本的文件操作方法,包括对文件系统中的目录和文件的操作,还有就是文件的读写操作等。通过运用System.IO.DirectoryInfo类和System.IO.FileInfo类我们可以轻易的完成与目录和文件相关的操作,而通过运用System.IO.StreamReader类和System.IO.StreamWriter类我们可以方便的完成与文件的读写相关的操作。 命名空间概览 下面的表格显示了System.IO命名空间中最重要的一些类,通过运用这些类我们就能完成基本的文件操作。 表1 类名功能和用途 BinaryReader、BinaryWriter 读写二进制数据 Directory、File、DirectoryInfo以及FileInfo 创建、删除并移动目录和文件,通过属性获取特定目录和文件的相关信息 FileStream 以随机方式访问文件 MemoryStream 访问存储在内存中的数据 StreamReader 、StreamWriter 读写文本数据信息 StringReader、StringWriter 运用字符串缓冲读写文本数据信息 运用DirectoryInfo类和FileInfo类 DirectoryInfo类和FileInfo类的基类都是FileSystemInfo类,这个类是一个抽象类,也就是说你不可以实例化该类,只能通过继承产生其子类并实例化其子类。然而你却可以运用由该类定义的各种属性,下面的表格显示了该类已经定义了的各种属性。 表2 属性功能和用途

db2top工具详解(翻译)

Database (d) Figure 2. Database screen 在数据库屏幕,db2top提供了一组对整个数据库的性能监控单元。 用户可以监视活动会话(MaxActSess),排序内存(SortMemory)和日志空间(LogUsed)。这些监测元素可以帮助用户确定这些元素的当前使用百分比。如果这些因素中的一个开始达到很高甚至100%时,用户应该开始调查发生了什么事。 当前时间和数据库开始时间(Start Time)相比能让我们了解数据库运行了多久。这个值结合其他检测元素去调查那些已存在一段时间的问题是非常有用的。 锁的使用(LockUsed)和升级(LockEscals)对缩小锁定问题非常有帮助。如果LockEscals 数量很大时,则增加LOCKLIST和MAXLOCKS数据库参数是一个好主意或者寻找那些引起这个问题的不良查询语句。 L_Reads,P_Reads和A_Reads代表逻辑读,物理读和异步读取。结合的命中率(HitRatio)值,这些变量对于评估大多数的读取发生在存储器中还是磁盘I / O里是非常重要的。因为磁盘的I / O比存储器存取慢得多,用户更喜欢访问在内存中的数据。当用户看到HitRatio 下降低则可以查看缓冲池(bufferpools)是不是不够大了,或是不是有查询进行了太多的全白扫描而导致页面数据从内存洗冲到磁盘。 和读类似,A_Writes代表异步写入,这表明数据页是由异步页清洁剂之前写的缓冲池空间是必需的。通过db2top 刷新频率这段时间内的写数量我们还能知道有多少写请求发生了。还能计算每次写入的平均花费时间这对分析I/O瓶颈引起的一些性能问题有所帮助。当A_Writes/Writes的比值越高则写I/O性能越高。 SortOvf代表排序溢出。如果用户发现这个数字变为非常高,就需要寻找查询了。排序溢出发生在SORTHEAP不足够大,导致排序(Sort)或HashJoin操作可能会溢出数据到临时空间。有时该值随着SORTHEAP增加而降低,但在其他情况下,可能没有多大帮助,如果进行排序的数据集比可分配给SORTHEAP内存大得多。如果请求的数据量超过缓冲池可容纳的临时空间大小那么就可能需要物理I/O来进行SORT或哈希链接在这种情况下排序溢出将是很大的瓶颈。因此优化查询来减少排序溢出的数量能显著提高系统的性能。

四种XML解析器比较

1.详解 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。 2)SAX SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。 而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。 选择DOM还是选择SAX?对于需要自己编写代码来处理XML文档的开发人员来说,选择DOM 还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档,而SAX采用的事件模型。 DOM解析器把XML文档转化为一个包含其内容的树,并可以对树进行遍历。用DOM解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文档,所以对性能和内存的要求比较高,尤其是遇到很大的XML文件的时候。由于它的遍历能力,DOM解析器常用于XML文档需要频繁的改变的服务中。 SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag.特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。 3)JDOM https://www.360docs.net/doc/9d9845232.html, JDOM的目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型,JDOM一直得到大力推广和促进。正在考虑通过“Java规范请求JSR-102” 将它最终用作“Java标准扩展”。从2000年初就已经开始了JDOM开发。 JDOM与DOM主要有两方面不同。首先,JDOM仅使用具体类而不使用接口。这在某些方面简化了API,但是也限制了灵活性。第二,API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用。 JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML问题”(根据学习曲线假定为20%)。JDOM对于大多数Java/XML应用程序来说当然是有用的,并且大多数开

用户配置文件操作详解

用户配置文件操作详解 系统崩溃了怎么办?重装系统!但每次重装系统时大家是否始终感觉新装系统的电脑操作不方便呢?例如进论坛要重新输入帐号密码,桌面背景也不是自己喜欢的图案,以前收藏的网页也不知所踪……其实面对这些问题,我们只要备份了用户配置文件,我们所有的个性化设置都能在系统重装后轻松恢复过来。 Windows 2000/XP/2003等操作系统都提供了非常完善的用户管理机制,每个登陆计算的账户都会有独立的文件夹用于保存该登陆账号的个性化信息,这种独立分开的方式也为我们备份和保护个人数据提供了可能。 1.找到个人数据的家 在了解如何备份个人数据之前我们首先要了解用户配置文件到底是如何工作的,只有了解了它的工作原理我们才能实现个人数据的轻松、快速备份。 当我们的操作系统(Windows 2000/XP/2003)安装完成后,在首次登录的时候操作系统会为当前登录的帐号建立一个用户配置文件夹,默认这个文件夹会位于“C:\Documents and Settings”下,我们可以选择“开始”-“运行”,输入“%SystemDrive%\Documents and Settings”即可打开该文件夹。这个文件夹默认会使用当前登录的用户名作为名字,但是如果在“Documents and Settings”文件夹中存在与当前登录用户名相同的文件夹,系统就会修改这个文件夹的名字以避免重复。例如,当前登录的用户名为ABC,默认系统会在第一次登陆的时候建立ABC文件夹,但是如果ABC文件夹存在则会尝试将名字改为“ABC.计算机名”,如果“ABC.计算机名”也存在,Windows则会尝试将文件夹命名为“ABC.计算机名.000”,如果仍然存在这样命名的文件夹则系统就会尝试“ABC.计算机名.001”、“ABC.计算机名.002”等。 2.挽救丢失的个人数据 有了上边的介绍的原理,接下来我们再尝试恢复丢失的用户数据就不再是一件非常困难的事情了,首先我们来解决开机后桌面背景、快捷方式和我的文档中数据统统丢失的问题。 Step 1 如果你只是想找回原来配置文件中的一些数据可以进入“Documents and Settings”文件夹,然后按照时间排序,你将可以看到多个以你当前用户名开头的文件夹,选择时间相对较久的那个并尝试双击进入,如果提示拒绝访问则可以注销计算机使用“administrator”帐号登录,登录后重新找到这个文件夹并在上边单击鼠标右键,选择“属性”-“安全”(如果找不到“安全”标签,可以选择“工具”-“文件夹选项”,取消使用简单文件共享前边的勾选),然后单击里边的“高级”按钮,在弹出的窗口中选择“所有者”,在里边选中“administrator”并勾选中下边的“替换子容器及对象的所有者”,如图1所示。设置完成后单击“应用”按钮。

db2top

DB2TOP(1) User Manuals DB2TOP(1) NAME db2top ? DB2 performance monitor SYNOPSIS db2top [?d dbname] [?n nodename] [?u username] [?p pass?- word] [?V schema] [?i interval] [?P ] [?b option] [?a] [?B] [?k] [?R] [?x] [?f file <+offset> ] [?D delimiter] [?C

XML创建与解析常用方法介绍

XML解析方式介绍 1.DOM4J(Document Object Model for Java) 虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始,它就一直处于开发之中。 为支持所有这些功能,DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections 类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性。 在添加灵活性、XPath集成和对大文档处理的目标时,DOM4J的目标与JDOM是一样的:针对Java 开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案,实现在本质上处理所有Java/XML问题的目标。在完成该目标时,它比JDOM更少强调防止不正确的应用程序行为。 DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML,特别值得一提的是连Sun的JAXM也在用DOM4J. 【优点】 ①大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法。 ②支持XPath。 ③有很好的性能。 【缺点】 ①大量使用了接口,API较为复杂。 2.SAX(Simple API for XML) SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。 选择DOM还是选择SAX?对于需要自己编写代码来处理XML文档的开发人员来说,选择DOM还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档,而SAX 采用的是事件模型。

Word的基本操作详解

第五章中文Word2000 第一节使用入门 一、启动Word2000中文版 方法1 [开始][程序][Microsoft Word] 方法2 用鼠标单击“开始”按钮,在打开“开始”菜单后,选择“新建Office文档”或“打开Office文档”(如果我们的计算机上已存有Word文档的话)并单击之。 方法3 如果“Office快捷工具栏”显示在屏幕上,用鼠标单击“Microsoft Word”图标按钮即可启动中文Word2000。 方法4 在桌面上制作一个中文Word2000的快捷键,以后只要用鼠标的左键双击此快捷键,就可以启动中文Word2000。 方法5 在“我的电脑”或“资源管理器”中,双击扩展名为.DOC 的文档。 二、Word2000工作环境 1、W ord2000应用程序窗口的组成 标题栏、菜单栏、工具栏和状态栏。 工具栏的显示与隐藏:[视图][工具栏],再在级联菜单中,选中要显示的工具栏或取消要隐藏的工具栏即可。 2、W ord2000文档窗口 标题栏、菜单栏、工具栏、标尺、水平、垂直滚动条,状态栏、工作区。 注意:

●在Word2000中的滚动条与常用窗口滚动条的区别。在垂直滚动条中多三个按钮,“选择浏览对象”按钮。在水平滚动条左边有“视图”按钮。 ●文字插入点标志、文件结束标志、段落结束标志: 3、使用菜单和对话框。:快捷菜单 4、帮助功能 1)Office 助手 2)[帮助][目录和索引] 3)屏幕提示:[帮助][这是什么?] 三、创建文档的操作步骤 1.新建文档 2.文字录入:包括文字、符号、图片、公式和艺术字等。要注意的 是:当用户输入文件达到行末时,WORD能自动移到下一行,称为自动换行,而不必按回车键,除非用户想开始新的一段或增加一空行。 3.编辑:用户可在WORD的帮助下进行插入、删除、修改、复制、移 动等操作。(剪贴板) 4.文件格式设置及排版:通过格式设置可以控制文件的外观显示。 例如设置黑体、斜体、下划线、使正文居中、左排等等。在文件中,还可以添加所需的图画与表格,从而将文件修饰得更加美观。 (工具按钮)

SAX解析XML原理

SAX是一个用于处理XML事件驱动的“推”模型,虽然它不是 W3C标准,但它却是一个得到了广泛认可的API。SAX解析器不像DOM那样建立一个完整的文档树,而是在读取文档时激活一系列事件,这些事件被推给事件处理器,然后由事件处理器提供对文档内容的访问。 常见的事件处理器有三种基本类型: ● 用于访问XML DTD内容的DTDHandler; ● 用于低级访问解析错误的ErrorHandler; ● 用于访问文档内容的ContentHandler,这也是最普遍使用的事件处理器。 图 2显示了SAX解析器如何通过一个回调机制报告事件。解析器读取输入文档并在处理文档时将每个事件推给文档处理器(MyContentHandler)。 与DOM相比,SAX解析器能提供更好的性能优势,它提供对XML文档内容的有效低级访问。SAX模型最大的优点是内存消耗小,因为整个文档无需一次加载到内存中,这使SAX解析器可以解析大于系统内存的文档。另外,你无需像在DOM中那样为所有节点创建对象。最后,SAX“推”模型可用于广播环境,能够同时注册多个ContentHandler,并行接收事件,而不是在一个管道中一个接一个地进行处理。 SAX的缺点是你必须实现多个事件处理程序以便能够处理所有到来的事件,同时你还必须在应用程序代码中维护这个事件状态,因为SAX解析器不能交流元信息,如DOM的父/子支持,所以你必须跟踪解析器处在文档层次的哪个位置。如此一来,你的文档越复杂,你的应用逻辑就越复杂。虽然没有必要一次将整个文档加载到内存中,但SAX解析器仍然需要解析整个文档,这点和DOM一样。 也许SAX面临的最大问题是它没有内置如XPath所提供的那些导航支持。再加上它的单遍解析,使它不能支持随机访问。这一限制也表现在名字空间上: 对有继承名字空间的元素不做注解。这些限制使SAX很少被用于操作或修改文档。 那些只需要单遍读取内容的应用程序可以从SAX解析中大大受益。很多B2B和EAI应用程序将XML用做封装格式,接收端用这种格式简单地接收所有数据。这就是SAX明显优于DOM的地方:因高效而获得高吞吐率。在SAX 2.0 中有一个内置的过滤机制,可以很轻松地输出一个文档子集或进行简单的文档转换。

相关文档
最新文档