日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

DOM Xerces类库使用方法

發(fā)布時(shí)間:2023/12/9 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DOM Xerces类库使用方法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

DOM Xerces類庫(kù)使用方法

Tuxedo中XML的歷史
  
如 今隨著XML逐漸成為主流的數(shù)據(jù)格式之一,自然而然地 Tuxedo將之作為一種基本緩沖類型予以支持。    Tuxedo 7.1 引入了XML緩沖類型,但迄今為止對(duì)于Tuxedo中的XML并無(wú)較多的論述。Tuxedo 7.1中并未攜帶真正的XML API,因?yàn)橥ǔUJ(rèn)為將開(kāi)發(fā)人員自己最喜歡的DOM或SAX實(shí)現(xiàn)合并到其應(yīng)用程序中是其自身的責(zé)任。
  現(xiàn)在,由于在Tuxedo內(nèi)嵌了Xerces 1.7 版本(來(lái)自Apache XML項(xiàng)目)庫(kù),所以伴隨Tuxedo 8.1提供了一套真正的XML API。8.1版本還包含了一個(gè)稱為xmlstockapp(xml股票程序)的XML示例。
  這一點(diǎn)為開(kāi)發(fā)人員增加了許多XML功能,例如XML解析,XML樹(shù)遍歷或構(gòu)建,以及XML格式化,從而不需要使用外部的產(chǎn)品何為XML?
  
XML經(jīng)常作為一種“語(yǔ)言”被提及,然而它實(shí)際上是一種用于描述文本緩沖區(qū)中的層次結(jié)構(gòu)數(shù)據(jù)集的標(biāo)準(zhǔn)格式。這種數(shù)據(jù)格式可以通過(guò)一種加強(qiáng)數(shù)據(jù)結(jié)構(gòu)和層次關(guān)系的本地語(yǔ)法(稱為DTD)來(lái)進(jìn)行控制。我如何在XML中進(jìn)行編碼?
  
XML并非一種語(yǔ)言,而是一種數(shù)據(jù)格式。編碼意味著使用一種API,從一個(gè)純文本緩沖區(qū)到數(shù)據(jù)樹(shù)來(lái)回進(jìn)行數(shù)據(jù)轉(zhuǎn)換,或者對(duì)數(shù)據(jù)樹(shù)進(jìn)行遍歷或操縱。想要了解如何使用XML進(jìn)行編碼,請(qǐng)參看下文“……一般任務(wù)”一節(jié)。有哪些可用的API對(duì)XML進(jìn)行操縱作?
  
目前存在數(shù)種標(biāo)準(zhǔn)API對(duì)XML進(jìn)行操縱,最著名的是DOM,SAX和XPATH。所有的API都針對(duì)不同語(yǔ)言具有不同的實(shí)現(xiàn),但是本文僅僅關(guān)注Tuxedo 8.1產(chǎn)品中包含的Xerces的C/C 實(shí)現(xiàn)。我應(yīng)在何時(shí)使用XML?
  
由于XML是一種標(biāo)準(zhǔn)的有組織的格式,如今它已經(jīng)成為一種廣為使用的便利格式來(lái)在不同系統(tǒng)間進(jìn)行數(shù)據(jù)交換。即使結(jié)構(gòu)上(DTD)略作改動(dòng)來(lái)添加一些子節(jié)點(diǎn)或新屬性,XML的自描述性和結(jié)構(gòu)化的方式也有助于數(shù)據(jù)的理解。XML也是易于閱讀的,而二進(jìn)制數(shù)據(jù)則不然。

然而XML仍具有一些缺點(diǎn):
  • 它使您的數(shù)據(jù)大幅膨脹(每個(gè)域?qū)⒃黾右粋€(gè)20字節(jié)左右的標(biāo)題,并且所有的二進(jìn)制域?qū)U(kuò)大為相應(yīng)的字符串表達(dá))。
  • 在進(jìn)行解析和格式化時(shí)它增加了CPU的開(kāi)銷,尤其是在解析和檢驗(yàn)文檔是否是“格式良好”時(shí)。
  • 其API均比較復(fù)雜。
因此XML是一種理想的集成語(yǔ)言,但是在系統(tǒng)內(nèi)部您可能并非處處都需要使用它。在Tuxedo中它通常用于同外部系統(tǒng)發(fā)送和接收數(shù)據(jù)。對(duì)于使用DOM API處理XML數(shù)據(jù)的程序的一般任務(wù):
  
這些任務(wù)并非只針對(duì)Tuxedo,而是適用于所有使用DOM處理XML數(shù)據(jù)的程序

初始化Xerces
  一旦您希望使用Xerces API進(jìn)行工作就必須強(qiáng)制進(jìn)行初始化:
/* initialise xerces */
try
{
??? XMLPlatformUtils::Initialize ();
}
catch (const XMLException & toCatch)
{
??? char *pMsg = XMLString::transcode (toCatch.getMessage ());
??? userlog ("Error during Xerces-c Initialization.\n"
??????????? "?? Exception message: %s", pMsg);
??? delete[]pMsg;
??? return -1;
}
解析XML文本
  當(dāng)XML 數(shù)據(jù)被接收時(shí),它通常是一個(gè)文本緩沖區(qū)或一個(gè)文件。DOM API是一種用于處理數(shù)據(jù)節(jié)點(diǎn)樹(shù)的API,這種節(jié)點(diǎn)樹(shù)通常由包含了屬性和其他元素的元素構(gòu)成。一個(gè)程序可以通過(guò)遞歸掃描元素節(jié)點(diǎn)來(lái)遍歷DOM樹(shù)。
  如果一個(gè)程序希 望通過(guò)層次結(jié)構(gòu),元素名稱或者屬性來(lái)訪問(wèn)緩沖區(qū)內(nèi)的數(shù)據(jù),該緩沖區(qū)首先需要被讀入并轉(zhuǎn)化為一棵數(shù)據(jù)樹(shù)。這一過(guò)程被稱為解析。要執(zhí)行文本解析您需要實(shí)現(xiàn)一個(gè) 來(lái)源類(LocalFileInputSource或MemBufInputSource)來(lái)容納將要解析的文本,并使用DOMParser的實(shí)現(xiàn)來(lái)進(jìn)行 解析。
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/framework/XMLFormatter.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>#include <xercesc/parsers/DOMParser.hpp>
#include <xercesc/dom/DOM_Node.hpp>/* parse a XML file */
char *xmlFileName = "./myfile.xml";
DOMParser *parser = 0;
DOM_Document document;
DOM_Element topLevel;LocalFileInputSource source (XMLString::transcode (xmlFileName));
 //
 //?? Create our parser, then set the parsing options.
 //?? discovers errors during the course of parsing the XML document.
 //
parser = new DOMParser ();
parser->setValidationScheme (DOMParser::Val_Never);
parser->setDoNamespaces (false);
parser->setDoSchema (false);
parser->setValidationSchemaFullChecking (false);
parser->setCreateEntityReferenceNodes (false);
parser->setToCreateXMLDeclTypeNode (true);
//
//?? Parse the XML file, catching any XML exceptions that might propagate
//?? out of it.
//
try?? {
??? parser->parse (source);
??? int errorCount = parser->getErrorCount ();
??? if (errorCount > 0)?????? {
?????? printf("%d error(s) occured during parsing config\n", errorCount);
?????? goto clean;
????? }
}
catch (const XMLException & e)?? {
??? printf("An error occured during parsing \n??? Message: %s\n"
?????????? "", e.getMessage ());
??? goto clean;
}
catch (const DOM_DOMException & e)?? {
??? printf("A DOM error occured during parsing config\n"
??????????? "Exception code: %d\n", e.code);
??? goto clean;
}
catch (...)?? {
??? printf ("An error occured during parsing config\n");
??? goto clean;
}
處理解析錯(cuò)誤
  一旦遇到解析錯(cuò)誤,獲取錯(cuò)誤發(fā)生的行號(hào)和列號(hào)來(lái)代替僅僅進(jìn)行錯(cuò)誤計(jì)數(shù)(或獲取一個(gè)致命異常)是更好的方式。這種做法能夠通過(guò)安裝錯(cuò)誤處理來(lái)輕松實(shí)現(xiàn):
#include <xercesc/sax/ErrorHandler.hpp>
class ExampleErrorHandler: public ErrorHandler {
??? virtual void anyError(char* type, const SAXParseException& exception) ;
public:
??? /** Default constructor */
??? ExampleErrorHandler(){};
??? /** Destructor */
??? ~ExampleErrorHandler() {};
??? void warning(const SAXParseException& exception){anyError("warning", exception); };
??? void error(const SAXParseException& exception) {anyError("error", exception); };
??? void fatalError(const SAXParseException& exception){anyError("fatal error", exception); };
??? void resetErrors() {};
};void ExampleErrorHandler::anyError(char* type, const SAXParseException& exception){
?????? printf("Parser %s line %d column %d: %ls %ls : %ls", type,
????????????? exception.getLineNumber () ,
????????????? exception.getColumnNumber () ,
????????????? exception.getPublicId?? () ,
????????????? exception.getSystemId () ,
????????????? exception.getMessage ());
}
在解析代碼中:
ExampleErrorHandler handler;
parser = new DOMParser ();
parser->setErrorHandler(&handler);
//
//?? Parse the XML file, catching any XML exceptions that might propagate
//?? out of it.
//
try?? {
??? parser->parse (source);
}
創(chuàng)建一棵DOM樹(shù)
  您可以按這種方式創(chuàng)建一棵DOM樹(shù)。它創(chuàng)建了根元素。
/* creates an empty dom tree */
DOM_DOMImplementation impl;
DOM_Document doc = impl.createDocument (0,?? // root element namespace URI.
???????????????????????????????????? rootname,?? // root element name
???????????????????????????????????? DOM_DocumentType ());// document type object (DTD).
/* fetch the root element */
DOM_Element rootElem = doc.getDocumentElement ();
對(duì)一個(gè)元素添加子元素
//Add new (empty) Element to the root element
????? DOM_Element parentNode = …;// parent is known
????? DOM_Element prodElem = doc->createElement (tagName);
????? parentNode->appendChild (prodElem);
刪除一個(gè)子元素
parentNode->removeChild (prodElem);
修改DOM樹(shù)元素的標(biāo)簽名稱
  一旦元素被創(chuàng)建您就不可以修改其標(biāo)簽名稱。

遍歷一個(gè)元素的子元素
  既然您已經(jīng)創(chuàng)建了一個(gè)XML元素節(jié)點(diǎn),您(可能)希望訪問(wèn)其子元素:
DOM_Element parent = …; // parent is known
DOM_Node child;
child = parent.getFirstChild ();
while?? (child != 0)???? {
??? //work with child??
??? …
??? //pickup next child
??? child?? = child.getNextSibling ();
}
按類型過(guò)濾子節(jié)點(diǎn)
  您可能希望忽略某些節(jié)點(diǎn),在這種情況下,檢查節(jié)點(diǎn)類型:
switch (child.getNodeType ())
?????? {
?????? case DOM_Node::ELEMENT_NODE:
???????????? …
???????? break;
?????? case DOM_Node::ATTRIBUTE_NODE:
???????????? …
???????? break;
?????? case DOM_Node::TEXT_NODE:
???????????? …
???????? break;
?????? case DOM_Node::CDATA_SECTION_NODE:
???????????? …
???????? break;
?????? case DOM_Node::ENTITY_REFERENCE_NODE:
???????????? …
???????? break;
?????? case DOM_Node::ENTITY_NODE:
???????????? …
???????? break;
?????? case DOM_Node::PROCESSING_INSTRUCTION_NODE:
???????????? …
???????? break;
?????? case DOM_Node::COMMENT_NODE:
???????????? …
???????? break;
?????? case DOM_Node::DOCUMENT_NODE:
???????????? …
???????? break;
?????? case DOM_Node::DOCUMENT_TYPE_NODE:
???????????? …
???????? break;
?????? case DOM_Node::DOCUMENT_FRAGMENT_NODE:
???????????? …
???????? break;
?????? case DOM_Node::NOTATION_NODE:
???????????? …
???????? break;
?????? case DOM_Node::XML_DECL_NODE:
???????????? …
???????? break;
?????? default:
???????????? …
?????? }
獲得一個(gè)元素的值
  一個(gè)元素內(nèi)的值存儲(chǔ)在一個(gè)文本子節(jié)點(diǎn)中:
DOM_Element parent = …; // parent is known
DOM_Node child;
DOM_Text value;
child = parent.getFirstChild ();
while?? (child != 0)???? {
??? //work with child??
??? if (child.getNodeType () == DOM_Node::TEXT_NODE)???? {
????? value = (DOM_Text &) child;
????? break;
??? }??????
??? //pickup next child
??? child?? = child.getNextSibling ();
}

DOMString unicodeValue = value.getData ();
//if you need the ascii value
char* asciiValue = unicodeValue.transcode ();
//work with your value

//free the value
delete []asciiValue ;
更改DOM樹(shù)元素的值
  另外,如果存在的話,不要忘記刪除之前的值:
DOM_Element parent = …; // parent is known
DOM_Node child;
DOM_Text value;
bool childFound = false;
child = parent.getFirstChild ();
while?? (child != 0)???? {
??? //work with child??
??? if (child.getNodeType () == DOM_Node::TEXT_NODE)???? {
????? value = (DOM_Text &) child;
????? childFound = true;
????? break;
??? }??
??? //pickup next child
??? child?? = child.getNextSibling ();
}
//now , maybe create a text node
if (!childFound) {
???????? value = doc->createTextNode ();
???????? parent.appendChild (value);
}
DOMString unicodeValue(asciiValue);
value.setData(unicodeValue);
添加或修改一個(gè)元素的屬性
  要添加(或設(shè)置)一個(gè)元素屬性的值,使用以下方法:
DOMString unicodename(asciiname);
????? DOMString unicodevalue(asciivalue);
????? DOM_Element element = …;// element is known
????? //Add new attribute to the element
????? element->setAttribute(unicodename, unicodevalue);
刪除一個(gè)元素的屬性
  要?jiǎng)h除一個(gè)元素的屬性,使用以下方法: [I.L.H1]??
DOMString unicodename(asciiname);
????? DOM_Element element = …;// element is known
????? //Add new attribute to the element
????? element->removeAttribute(unicodename);
遍歷一個(gè)元素的屬性
  要瀏覽一個(gè)元素的所有屬性,您可以按以下方法加以實(shí)現(xiàn):
//loop through this element attributes and fill the config structure
????? DOMString unicodename;
????? DOMString unicodevalue;
????? DOM_NamedNodeMap attributes;
????? DOM_Element element = …;// element is known
????? attributes = element.getAttributes ();
????? int attrCount;
????? attrCount = attributes.getLength ();
????? for (i = 0; i < attrCount; i )???? {
????????? DOM_Node attribute = attributes.item (i);
????????? //work with the attribute
????????? unicodename = attribute.getNodeName ();
????????? unicodevalue= attribute. getNodeValue ();
????????? //if need ascii values, get them
????????? char* asciiname= unicodename.transcode ();
????????? char* asciivalue = unicodevalue.transcode ();
????????? …
????????? //but don't forget to release them
????????? delete []asciiname;
????????? delete []asciivalue;
????? }
將DOM樹(shù)作為文本緩沖區(qū)打印輸出
  并沒(méi)有直接的方法來(lái)將DOM樹(shù)格式化為XML文本緩沖區(qū)。最簡(jiǎn)單的方法是參考Xerces 1.7中DOMPrint的示例,或者查看一下本文附帶的XFML庫(kù)中的XMLimplementation.hxx文件。
  具體的想法是實(shí)現(xiàn)一個(gè)函數(shù),該函數(shù)將遍歷所有節(jié)點(diǎn)并將節(jié)點(diǎn)及其屬性打印輸出。
  Tuxedo中的XML示例:
  所有附帶的代碼示例均經(jīng)過(guò)編譯,并在Microsoft Windows NT下使用。由于示例中依賴的庫(kù)均已在Unix中經(jīng)過(guò)編譯,移植到Unix的工作量應(yīng)該很小。

轉(zhuǎn)載于:https://blog.51cto.com/panpan/187272

總結(jié)

以上是生活随笔為你收集整理的DOM Xerces类库使用方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。