⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlfile.cpp

📁 一个英国人写的GIS查看/编辑工具。支持标准的shapefile地图文件格式和coverage地图文件格式。同时可以编辑相应的dbf文件。
💻 CPP
字号:
//////////////////////////////////////////////////////
//
// NRDB Pro - Spatial database and mapping application
//
// Copyright (c) 1989-2004 Richard D. Alexander
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// NRDB Pro is part of the Natural Resources Database Project 
// 
// Homepage: http://www.nrdb.co.uk/
// Users' Forum: http://nrdb.mypalawan.info/
// 

#include "stdafx.h"
#include "xmlfile.h"

///////////////////////////////////////////////////////////////////////////////

CXMLObj::CXMLObj()
{
   m_pNext = NULL;
   m_pChild = NULL;
}

CXMLObj::~CXMLObj()
{
   // Delete any objects

   if (m_pChild != NULL)
   {
      delete m_pChild;
      m_pChild = NULL;
   }

   if (m_pNext != NULL)
   {
      delete m_pNext;
      m_pNext = NULL;
   }
}

///////////////////////////////////////////////////////////////////////////////

BOOL CXMLFile::Write(LPCSTR sFile)
{
   BOOL bOK = FALSE;

   // Writes a XML data to the file specified

   FILE* pFile = fopen(sFile, "w");
   if (pFile != NULL)
   {
      bOK = CXMLObj::Write(pFile);

      fclose(pFile);
   }

   return bOK;
}

///////////////////////////////////////////////////////////////////////////////

BOOL CXMLFile::Read(LPCSTR sFile)
{
   BOOL bOK = FALSE;

   FILE *pFile = fopen(sFile, "r");
   if (pFile != NULL)
   {
      bOK = CXMLObj::Read(pFile);

      fclose(pFile);
   }
   return bOK;
}

///////////////////////////////////////////////////////////////////////////////

BOOL CXMLObj::Read(FILE *pFile, char ch)
{
   BOOL bOK = TRUE;
   CString sName;

   // Skip white space

   if (ch == 0) ch = fgetc(pFile);
   while (isspace(ch)) ch = fgetc(pFile);

   // Read tag

   if (ch == '<')
   {
      // Get name of tag

       ch = fgetc(pFile);
       while (isalnum(ch)) 
       {
          m_sName += ch;
          ch = fgetc(pFile);
       };

       // Retrieve attributes

       if (isspace(ch))
       {
          ReadAttr(pFile);
          ch = fgetc(pFile);
       };       

       // If inline tag then return 

       if (ch == '/')
       {
          ch = fgetc(pFile);
          bOK = ch == '>';
          return bOK;
       }

       // Skip tag closing

       
       ASSERT(ch == '>');
       if (ch != '>')
       { 
          bOK = FALSE;          
       }

       while (bOK)
       {          
          // Read value (if any)

          ch = fgetc(pFile);            
          while (isspace(ch)) ch = fgetc(pFile);

          while (ch != '<' && ch != EOF)
          {
             m_sValue += ch;
             ch = fgetc(pFile);
          }

          // Get next character

          ch = fgetc(pFile);

          // Closing tag
          
          if (ch == '/') 
          {             
             ch = fgetc(pFile);
             while (isalnum(ch))
             {
                sName += ch;
                ch = fgetc(pFile);
             }
             // Invalid tag

             if (sName != m_sName) bOK = FALSE;

             // Find closing tag

             while (ch != '>' && ch != EOF)
             {
                ch = fgetc(pFile);
             }
             return bOK;
          }

          // Child tag
                    
          ungetc(ch, pFile); 

          // Find next available child object

          CXMLObj **pChild = &m_pChild;
          while (*pChild != NULL)
          {
             pChild = &(*pChild)->m_pNext;
          }
          (*pChild) = new CXMLObj;

          bOK = (*pChild)->Read(pFile, '<');

       };
   } 

   // Invalid XML
   else
   {
      bOK = FALSE;
   }
   
   return bOK;
}

///////////////////////////////////////////////////////////////////////////////

BOOL CXMLObj::ReadAttr(FILE *pFile)
{
   BOOL bOK = TRUE;
   char ch = fgetc(pFile);
 
   while (ch != '>' && ch != '/' && ch != EOF)
   {
      // Reset
      CXMLAttr attr;

      // Skip space
      
      while (isspace(ch)) ch = fgetc(pFile);

      if (isalpha(ch))
      {     
         // Get name

         while (ch != '=' && ch != EOF)
         {
            attr.m_sName += ch;  
            ch = fgetc(pFile);
         }

         // Get opening quote

         ch = fgetc(pFile);

         // Get value

         if (ch == '\"')
         {
            ch = fgetc(pFile);
            while (ch != '\"' && ch != EOF)
            {
               attr.m_sValue += ch;
               ch = fgetc(pFile);
            }; 

            // Add to list 

            m_aAttr.Add(attr);
         } else
         {
            bOK = FALSE;
         }
      };

      ch = fgetc(pFile);
   }

   // Unwind last character

   ungetc(ch, pFile);
   
   if (feof(pFile)) bOK = FALSE;
   return bOK;
}

///////////////////////////////////////////////////////////////////////////////

BOOL CXMLObj::Write(FILE *pFile)
{   
   // Write tag

   putc('<', pFile);
   fputs(m_sName, pFile);

   // Write attributes

   for (int i = 0; i < m_aAttr.GetSize(); i++)
   {
      putc(' ', pFile);
      fputs(m_aAttr[i].m_sName, pFile);
      fputs("=\"", pFile);
      fputs(m_aAttr[i].m_sValue, pFile);     
      putc('\"', pFile);
   }

   // Close tag

   putc('>', pFile);

   // Cannot have a value and a child

   ASSERT(m_sValue == "" || m_pChild == NULL);

   // if there is a value then write this   

   if (m_sValue != "")
   {
      fputs(m_sValue, pFile);
   }

   // Write the child

   else if (m_pChild != NULL)
   {      
      m_pChild->Write(pFile);    
   }

   // Close the tag

   fputs("</", pFile);
   fputs(m_sName, pFile);
   putc('>', pFile);
   putc('\n', pFile);

   // Write the next

   if (m_pNext != NULL)
   {
      putc('\n', pFile);
      m_pNext->Write(pFile);
      putc('\n', pFile);
   }

   return ferror(pFile) == 0;
}

///////////////////////////////////////////////////////////////////////////////
//
// Search through the list of attributes and returns the matching value (if any)
//

CString CXMLObj::GetAttr(LPCSTR sName)
{
   for (int i = 0; i < m_aAttr.GetSize(); i++)
   {
      if (m_aAttr[i].m_sName == sName) return m_aAttr[i].m_sValue;
   }
   return "";
}

///////////////////////////////////////////////////////////////////////////////
//
// Searches through parent and child objects until finds matching names and
// then returns child value


CXMLObj* CXMLObj::GetXMLObj(LPCSTR sTag, LPCSTR sTagChild)
{
   CXMLObj *pXMLObj = NULL;
   
   // If the tag matches then don't move down one level

   if (sTag == m_sName) pXMLObj = this;
   else pXMLObj = m_pChild;

   while (pXMLObj != NULL)
   {
      if (pXMLObj->m_sName == sTag)
      {
         CXMLObj *pXMLChild = pXMLObj->m_pChild;
         while (pXMLChild != NULL)
         {
            if (pXMLChild->m_sName == sTagChild)
            {
               return pXMLChild;
            }
            pXMLChild = pXMLChild->m_pNext;
         }                       
      }
      pXMLObj = pXMLObj->m_pNext;
   }
   return NULL;
}

//////////////////////////////////////////////////////////////////////////////

CString CXMLObj::GetString(LPCSTR sTag, LPCSTR sTagChild)
{
   CXMLObj *pXMLObj = GetXMLObj(sTag, sTagChild);
   if (pXMLObj != NULL) return pXMLObj->m_sValue;
   else return "";   
}

///////////////////////////////////////////////////////////////////////////////
//
// Retrieves an integer value for a matching tag and child tag
//

int CXMLObj::GetInteger(LPCSTR sTag, LPCSTR sTagChild)
{
   int i = 0;
   CString s = GetString(sTag, sTagChild);
   sscanf(s, "%i", &i);
   return i;
}

double CXMLObj::GetDouble(LPCSTR sTag, LPCSTR sTagChild)
{
   double d = 0;
   CString s = GetString(sTag, sTagChild);
   sscanf(s, "%lf", &d);
   return d;
}

///////////////////////////////////////////////////////////////////////////////
//
// Adds the object as the next child
//

void CXMLObj::AddChild(CXMLObj *pXMLObj)
{
   if (m_pChild == NULL)
   {
      m_pChild = pXMLObj;
   } else
   {
      CXMLObj *pChild = m_pChild;

      while (pChild->m_pNext != NULL)
      {
         pChild = pChild->m_pNext;
      }
      pChild->m_pNext = pXMLObj;
   }
}

///////////////////////////////////////////////////////////////////////////////
//
// Finds the next XML objet with the correponding name. pXMLObj must initially
// have value NULL
//

BOOL CXMLObj::GetChild(LPCSTR sName, CXMLObj *&pXMLObj)
{
   // Return first object

   if (pXMLObj == NULL) 
   {
      pXMLObj = m_pChild;
      return pXMLObj != NULL;
   }

   CXMLObj *pXMLChild = m_pChild;
  
   while (pXMLChild != NULL)
   {
      if (pXMLChild->m_sName == sName && pXMLChild == pXMLObj)
      {
         pXMLObj = pXMLChild->m_pNext;
         return pXMLObj != NULL;
      }
      pXMLChild = pXMLChild->m_pNext;

   };
   return FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -