xml节点的删除出错

  1. //XercesParserXml.h
  2. #ifndef XERCES_PARSER_XML_H__
  3. #define XERCES_PARSER_XML_H__
  4. #include <string>
  5. class XercesParserXml {
  6. public:
  7.     bool has(const std::string& srcByte, const std::string& node) const;
  8.     std::string get(const std::string& srcByte, const std::string& node) const;
  9.     bool set(std::string& srcByte, const std::string& node, const std::string& value);
  10.     bool del(std::string& srcByte, const std::string& node);
  11. private:
  12. };
  13. #endif
  14. //XercesParserXml.cpp
  15. #include "XercesParserXml.h"
  16. #include <xercesc/parsers/XercesDOMParser.hpp>
  17. #include <xercesc/dom/DOM.hpp>
  18. #include <xercesc/sax/HandlerBase.hpp>
  19. #include <xercesc/util/XMLString.hpp>
  20. #include <xercesc/util/PlatformUtils.hpp>
  21. #include <xercesc/framework/MemBufInputSource.hpp>
  22. #if defined(XERCES_NEW_IOSTREAMS)
  23. #include <iostream>
  24. #else
  25. #include <iostream>
  26. #include <iostream.h>
  27. #endif
  28. #include <vector>
  29. XERCES_CPP_NAMESPACE_USE
  30. DOMNode* getNode(DOMNode* node, const char* nodeName)
  31. {
  32.     //char* ptr = (char *)nodeName;
  33.     char ptr[4096] = {0};
  34.     sprintf(ptr, "%s", nodeName);
  35.     if (NULL == ptr)
  36.         return NULL;
  37.     char* d = ".";
  38.     char* p = NULL;
  39.     p = strtok(ptr, d);
  40.     std::vector<std::string> vec;
  41.     while (p) 
  42.     {
  43.         //printf("name: %s/n", p);
  44.         vec.push_back(p);
  45.         p = strtok(NULL, d);
  46.     }
  47.     DOMNode* child;
  48.     DOMNode* curNode = node;
  49.     for (unsigned int i = 1; i < vec.size(); i++) 
  50.     {
  51.         //std::cout << vec[i] << std::endl;
  52.         if (0 == curNode) {
  53.             return NULL;
  54.         }
  55.         for (child = curNode->getFirstChild(); child != 0; child = child->getNextSibling()) { // have no child ???
  56.             char *name = XMLString::transcode(child->getNodeName());
  57.             if (vec[i] == name) {
  58.                 //printf("vec[%d]: %s/tname: %s/n", i, vec[i].c_str(), name);
  59.                 XMLString::release(&name);
  60.                 curNode = child;
  61.                 break;
  62.             }
  63.             XMLString::release(&name);
  64.             if (child == curNode->getLastChild()) {
  65.                 std::cout << "such node isn't exist" << std::endl;
  66.                 return NULL;
  67.             }
  68.         }
  69.     }
  70.     return curNode;
  71. }
  72. class XStr
  73. {
  74. public :
  75.     // -----------------------------------------------------------------------
  76.     // Constructors and Destructor
  77.     // -----------------------------------------------------------------------
  78.     XStr(const charconst toTranscode)
  79.     {
  80.         // Call the private transcoding method
  81.         fUnicodeForm = XMLString::transcode(toTranscode);
  82.     }
  83.     ~XStr()
  84.     {
  85.         XMLString::release(&fUnicodeForm);
  86.     }
  87.     // -----------------------------------------------------------------------
  88.     // Getter methods
  89.     // -----------------------------------------------------------------------
  90.     const XMLCh* unicodeForm() const
  91.     {
  92.         return fUnicodeForm;
  93.     }
  94. private :
  95.     // -----------------------------------------------------------------------
  96.     // Private data members
  97.     //
  98.     // fUnicodeForm
  99.     // This is the Unicode XMLCh format of the string.
  100.     // -----------------------------------------------------------------------
  101.     XMLCh* fUnicodeForm;
  102. };
  103. #define X(str) XStr(str).unicodeForm()
  104. bool XercesParserXml::has(const std::string& srcBytes, const std::string& node) const
  105. {
  106.     // init
  107.     try {
  108.         XMLPlatformUtils::Initialize();
  109.     }
  110.     catch (const XMLException& toCatch) {
  111.         char* message = XMLString::transcode(toCatch.getMessage());
  112.         std::cout << "Error during initialization! :/n"
  113.              << message << "/n";
  114.         XMLString::release(&message);
  115.         return false;
  116.     }
  117.     // 1. load the right xml bytes from signal tree
  118.     XercesDOMParser* parser = new XercesDOMParser();
  119.     if (NULL == parser) {
  120.         return false;
  121.     }
  122.     parser->setValidationScheme(XercesDOMParser::Val_Always);
  123.     parser->setDoNamespaces(true); // optional
  124.     ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase();
  125.     parser->setErrorHandler(errHandler);
  126.     InputSource* pInputSource = new MemBufInputSource((XMLByte *)srcBytes.c_str(), srcBytes.size(), X("GUID"));
  127.     if (NULL == pInputSource) {
  128.         delete parser;
  129.         delete errHandler;
  130.         return false;
  131.     }
  132.     // 2. parser the xml bytes to a DOM tree
  133.     parser->parse(*pInputSource);
  134.     DOMDocument* doc = parser->getDocument();
  135.     if (NULL == doc) {
  136.         delete parser;
  137.         delete errHandler;
  138.         delete pInputSource;
  139.         return false;
  140.     }
  141.     // 3. find node of parameter in DOM tree
  142.     DOMElement* rootElem = NULL;
  143.     rootElem = doc->getDocumentElement();
  144.     DOMNode* testNode = NULL;
  145.     testNode = getNode(rootElem, node.c_str());
  146.     // release source
  147.     delete parser;
  148.     delete errHandler;
  149.     delete pInputSource;
  150.     //doc->release();
  151.     if (testNode == NULL) {
  152.         return false;
  153.     }
  154.     else {
  155.         return true;
  156.     }
  157. }
  158. std::string XercesParserXml::get(const std::string& srcBytes, const std::string& node) const
  159. {
  160.     // init
  161.     try {
  162.         XMLPlatformUtils::Initialize();
  163.     }
  164.     catch (const XMLException& toCatch) {
  165.         char* message = XMLString::transcode(toCatch.getMessage());
  166.         std::cout << "Error during initialization! :/n"
  167.              << message << "/n";
  168.         XMLString::release(&message);
  169.         return "";
  170.     }
  171.     // 1. load the right xml bytes from signal tree
  172.     XercesDOMParser* parser = new XercesDOMParser();
  173.     if (NULL == parser) {
  174.         return "";
  175.     }
  176.     parser->setValidationScheme(XercesDOMParser::Val_Always);
  177.     parser->setDoNamespaces(true); // optional
  178.     ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase();
  179.     parser->setErrorHandler(errHandler);
  180.     InputSource* pInputSource = new MemBufInputSource((XMLByte *)srcBytes.c_str(), srcBytes.size(), X("GUID"));
  181.     if (NULL == pInputSource) {
  182.         delete parser;
  183.         delete errHandler;
  184.         return "";
  185.     }
  186.     // 2. parser the xml bytes to a DOM tree
  187.     parser->parse(*pInputSource);
  188.     DOMDocument* doc = parser->getDocument();
  189.     if (NULL == doc) {
  190.         delete parser;
  191.         delete errHandler;
  192.         delete pInputSource;
  193.         return "";
  194.     }
  195.     // 3. find node of parameter in DOM tree
  196.     DOMElement* rootElem = NULL;
  197.     rootElem = doc->getDocumentElement();
  198.     DOMNode* testNode = NULL;
  199.     testNode = getNode(rootElem, node.c_str());
  200.     // get content
  201.     std::string result;
  202.     char* nodeValue = NULL;
  203.     if (testNode) {
  204.         nodeValue = XMLString::transcode(testNode->getTextContent());
  205.         result = nodeValue;
  206.         XMLString::release(&nodeValue);
  207.     }
  208.     // release source
  209.     delete parser;
  210.     delete errHandler;
  211.     delete pInputSource;
  212.     //doc->release();
  213.     return result;
  214. }
  215. bool XercesParserXml::set(std::string& srcBytes, const std::string& node, const std::string& value)
  216. {
  217.     // init
  218.     try {
  219.         XMLPlatformUtils::Initialize();
  220.     }
  221.     catch (const XMLException& toCatch) {
  222.         char* message = XMLString::transcode(toCatch.getMessage());
  223.         std::cout << "Error during initialization! :/n"
  224.              << message << "/n";
  225.         XMLString::release(&message);
  226.         return false;
  227.     }
  228.     // 1. load the right xml bytes from signal tree
  229.     XercesDOMParser* parser = new XercesDOMParser();
  230.     if (NULL == parser) {
  231.         return false;
  232.     }
  233.     parser->setValidationScheme(XercesDOMParser::Val_Always);
  234.     parser->setDoNamespaces(true); // optional
  235.     ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase();
  236.     parser->setErrorHandler(errHandler);
  237.     InputSource* pInputSource = new MemBufInputSource((XMLByte *)srcBytes.c_str(), srcBytes.size(), X("GUID"));
  238.     if (NULL == pInputSource) {
  239.         delete parser;
  240.         delete errHandler;
  241.         return false;
  242.     }
  243.     // 2. parser the xml bytes to a DOM tree
  244.     parser->parse(*pInputSource);
  245.     DOMDocument* doc = parser->getDocument();
  246.     if (NULL == doc) {
  247.         delete parser;
  248.         delete errHandler;
  249.         delete pInputSource;
  250.         return false;
  251.     }
  252.     // 3. find node of parameter in DOM tree
  253.     DOMElement* rootElem = NULL;
  254.     rootElem = doc->getDocumentElement();
  255.     DOMNode* testNode = NULL;
  256.     testNode = getNode(rootElem, node.c_str());
  257.     // 4. set new content
  258.     if (testNode) {
  259.         testNode->setTextContent(X(value.c_str()));
  260.     }
  261.     // 5. serialize DOM tree and save it
  262.     char* result;
  263.     DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(X("Core"));
  264.     if (NULL == impl) {
  265.         XERCES_STD_QUALIFIER cerr << "Requested implementation is not supported" << XERCES_STD_QUALIFIER endl;
  266.         XMLPlatformUtils::Terminate();
  267.         delete parser;
  268.         delete errHandler;
  269.         delete pInputSource;
  270.         return false;
  271.     }
  272.     DOMWriter* theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter();
  273.     if (NULL == theSerializer) {
  274.         delete parser;
  275.         delete errHandler;
  276.         delete pInputSource;
  277.         return false;
  278.     }
  279.     if (theSerializer->canSetFeature(XMLUni::fgDOMWRTDiscardDefaultContent, true))
  280.         theSerializer->setFeature(XMLUni::fgDOMWRTDiscardDefaultContent, true);
  281.     if (theSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true))
  282.         theSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true);
  283.     XMLCh* unicodeStr = theSerializer->writeToString(*rootElem);
  284.     result = XMLString::transcode(unicodeStr);
  285.     srcBytes = result;
  286.     //printf("result: %s/n", result);
  287.     XMLString::release(&unicodeStr);
  288.     XMLString::release(&result);
  289.     // release source
  290.     theSerializer->release();
  291.     delete parser;
  292.     delete errHandler;
  293.     delete pInputSource;
  294.     return true;
  295. }
  296. bool XercesParserXml::del(std::string& srcBytes, const std::string& node)
  297. {
  298.     // init
  299.     try {
  300.         XMLPlatformUtils::Initialize();
  301.     }
  302.     catch (const XMLException& toCatch) {
  303.         char* message = XMLString::transcode(toCatch.getMessage());
  304.         std::cout << "Error during initialization! :/n"
  305.              << message << "/n";
  306.         XMLString::release(&message);
  307.         return false;
  308.     }
  309.     // 1. load the right xml bytes from signal tree
  310.     XercesDOMParser* parser = new XercesDOMParser();
  311.     if (NULL == parser) {
  312.         return false;
  313.     }
  314.     parser->setValidationScheme(XercesDOMParser::Val_Always);
  315.     parser->setDoNamespaces(true); // optional
  316.     ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase();
  317.     parser->setErrorHandler(errHandler);
  318.     InputSource* pInputSource = new MemBufInputSource((XMLByte *)srcBytes.c_str(), srcBytes.size(), X("GUID"));
  319.     if (NULL == pInputSource) {
  320.         delete parser;
  321.         delete errHandler;
  322.         return false;
  323.     }
  324.     // 2. parser the xml bytes to a DOM tree
  325.     parser->parse(*pInputSource);   
  326.     DOMDocument* doc = parser->getDocument();
  327.     if (NULL == doc) {
  328.         delete parser;
  329.         delete errHandler;
  330.         delete pInputSource;
  331.         return false;
  332.     }
  333.     // 3. find node of parameter in DOM tree
  334.     DOMElement* rootElem = NULL;
  335.     rootElem = doc->getDocumentElement();
  336.     DOMNode* testNode = NULL;
  337.     testNode = getNode(rootElem, node.c_str());
  338.     if (NULL == testNode) {
  339.         delete parser;
  340.         delete errHandler;
  341.         delete pInputSource;
  342.         return false;
  343.     }
  344.     // 4. remove identifier node from DOM tree
  345.     DOMNode* parentNode = testNode->getParentNode();
  346.     DOMNode* oldNode = parentNode->removeChild(testNode);
  347.     oldNode->release();
  348.     // 5. serialize DOM tree and save it
  349.     char* result;
  350.     DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(X("Core"));
  351.     if (NULL == impl) {
  352.         XERCES_STD_QUALIFIER cerr << "Requested implementation is not supported" << XERCES_STD_QUALIFIER endl;
  353.         XMLPlatformUtils::Terminate();
  354.         delete parser;
  355.         delete errHandler;
  356.         delete pInputSource;
  357.         return false;
  358.     }
  359.     DOMWriter* theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter();
  360.     if (NULL == theSerializer) {
  361.         delete parser;
  362.         delete errHandler;
  363.         delete pInputSource;
  364.         return false;
  365.     }
  366.     if (theSerializer->canSetFeature(XMLUni::fgDOMWRTDiscardDefaultContent, true))
  367.         theSerializer->setFeature(XMLUni::fgDOMWRTDiscardDefaultContent, true);
  368.     if (theSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true))
  369.         theSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true);
  370.     XMLCh* unicodeStr = theSerializer->writeToString(*rootElem);
  371.     result = XMLString::transcode(unicodeStr);
  372.     srcBytes = result;
  373.     //printf("result: %s/n", result);
  374.     XMLString::release(&unicodeStr);
  375.     XMLString::release(&result);
  376.     // release source
  377.     theSerializer->release();
  378.     delete parser;
  379.     delete errHandler;
  380.     delete pInputSource;
  381.     return true;
  382. }
  383. int main()
  384. {
  385.     char* xmlFile = "x2.xml";
  386.     char buf[4096] = {0};
  387.     FILE* fp = fopen(xmlFile, "rb");
  388.     if (!fp) 
  389.     {
  390.         perror(xmlFile);
  391.         exit(1);
  392.     }
  393.     size_t size;
  394.     size = fread(buf, 1, sizeof(buf), fp);
  395.     fclose(fp);
  396.     std::cout << "size to be parser: " << size << std::endl;
  397.     std::string srcDocBytes;
  398.     srcDocBytes.assign(buf, size);
  399.     std::string backup = srcDocBytes;
  400.     XercesParserXml xml;
  401.     bool flag = false;
  402.     char testNode[1000] = {0};
  403.     //其中各结点以“.”分隔,格式:root.child.grandson
  404.     sprintf(testNode, "%s""SendRoutingInfoRes.imsi"); 
  405.     std::string result;
  406.     for (int i = 0; i < 1; i++)
  407.     {
  408.         srcDocBytes = backup;
  409.         printf("/nfind node test ... /n");
  410.         flag = xml.has(srcDocBytes, testNode);
  411.         printf("/nget node test .../n");
  412.         result = xml.get(srcDocBytes, testNode);
  413.         printf("get value: %s/n", result.c_str());
  414.         printf("/nset node test .../n");
  415.         xml.set(srcDocBytes, testNode, "gnu means gnu not unix");
  416.         printf("new content: %s/n", srcDocBytes.c_str());
  417.         printf("/nremove test .../n");
  418.         xml.del(srcDocBytes, testNode);
  419.         printf("after del operation: %s/n", srcDocBytes.c_str());
  420.     }
  421.     if (flag) {
  422.         printf("%s has found/n", testNode);
  423.     }
  424.     else {
  425.         printf("%s hasn't found/n", testNode);
  426.     }
  427. }

        从网上下了一段操作xml文件的代码,这段代码可以修改、删除、访问xml中的一个节点,感觉不是很有用,因为我想找的是能根据xml文件中元素的名称得到元素值的基本方法,根据元素名和该元素的属性名得到属性值的基本方法。

        既然已经把代码下下来了,就运行了一下,结果报错了,调试的时候发现是引用KERNEL32.DLL的时候出错了,这个错误有些奇怪,出错的代码是parser->parse(*pInputSource);这一行,经过观察发现其他的函数也有与这段完全相同的代码,但是其他函数为什么没有出错呢?为什么完全相同的一段代码放在这里不会错,放在那里就报错了?

        花了很多时间琢磨,终于找到原因了,那段代码本身是没有错误的,直接原因是main函数对子函数的调用顺序导致的,实质原因是,几个子函数对资源释放的不彻底导致的,可以这样类比,一个函数set去改写一个文本文件text,set改写了text后,没有释放资源,另一个函数del又去删除text,这时就发生资源访问冲突了。

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值